数据范围2000,O(n*n)
的算法可以过。
类似于双指针,找最小的那个字母对于的指针,之后将其向前或向后进行移动。如果两个字母相同,则判断哪个位置取了可以让之后的字符串更小即可。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 2e3 + 21;
char s[N];
char ans[N];
int main()
{
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i) getchar(), scanf("%c", &s[i]);
int i = 1, j = n;
int cnt = 1;
while(i <= j) {
if(s[i] > s[j]) {
ans[cnt++] = s[j--];
} else if(s[i] < s[j]) {
ans[cnt++] = s[i++];
} else { // 这一块优化优化就是 O(n)了
int ii = i+1, jj = j-1;
int fg = -1;
while(ii < jj) {
if(s[ii] > s[jj]) {
fg = 2;
break;
} else if(s[ii] < s[jj]) {
fg = 1;
break;
}
ii++,jj--;
}
if(fg == 2) {
ans[cnt++] = s[j--];
} else if(fg == 1) {
ans[cnt++] = s[i++];
} else {
ans[cnt++] = s[j--];
}
}
}
for(int i = 1; i <= n; ++i) {
printf("%c",ans[i]);
if(i % 80 == 0) puts("");
}
}