poj3617 Best Cow Line

题目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 != '\n' && 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("\n");
    }
    for(; ii < N; ++ii) printf("%c", res[ii]);
    printf("\n");
}
posted @ 2020-01-22 21:15  patrolli  阅读(95)  评论(0编辑  收藏  举报