题目:http://poj.org/problem?id=3617
给定一个字符序列S,按一定规则输出最小字典序的结果,规则是:如果S的头部字符小于尾部字符,那么将S的头部字符加到输出字符串,然后删除这个字符,得到新的头部字符,反之同样。
输入样例:
6
A
C
D
B
C
B
输出样例:
ABCBCD
思路:
-
可以将S颠倒次序得到S',这样依次比较S和S'的头字符,如果分出大小就将小的那个加入输出,并且需要对这两个字符串都做删除更新处理,如果相同,则继续比较下一字符,但取出的仍是头部字符。
-
可以省略S'的开销,用两个指针在S的头尾操作,这个过程比较精妙
思路:
#include <iostream>
using namespace std;
const int maxn = 2002;
char cows[maxn];
char res[maxn];
char cowscpy[maxn];
int main(){
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int N; scanf("%d", &N);
int idx = 0;
char c;
while(1){
c = getchar();
if(c != '
' && c != ' ') cows[idx++] = c;
if(idx >= N) break;
}
//reverse the cows
for(int idx = 0, l = 0, r = N-1; idx < N; ){
bool left = false;
for(int i = 0; l + i < r; ++i){ //only in the equal case we have to move the two pointers...
if(cows[l+i] < cows[r-i]) {left = true; break;}
else if(cows[r-i] < cows[l+i]) { left = false; break;}
}
if(left) res[idx++] = cows[l++];
else res[idx++] = cows[r--];
}
int rows = N / 80;
int ii = 0;
for(int i = 1; i <= rows; ++i){
for(; ii < 80 * i; ++ii){
printf("%c", res[ii]);
}
printf("
");
}
for(; ii < N; ++ii) printf("%c", res[ii]);
printf("
");
}