給定長度爲 N 的字符串 S,現在要構造一個長度爲 N 的字符串 T。T 開始的時候是空串,然後反覆進行以下兩個操作之一,直至 S 爲空串:
- 從 S 的頭部刪除一個字符,加到 T 的尾部
- 從 S 的尾部刪除一個字符,加到 T 的尾部
求字典序儘可能小的字符串 T。
輸入格式
一個整數 T,表示有多少組測試數據。
接下來的 T 組測試數據,每組測試數據第一行是一個正整數 N (0 <= N <= 2000),表示字符串的長度。
第二行是一個長度爲 N 的字符串 S。
保證字符串出現的字符都是可打印字符。
輸出格式
輸出一個字符串,表示題目要求的字符串 T。
樣例輸入
1
6
ACDBCB
樣例輸出
ABCBCD
方法1,本人寫的
#include<stdio.h>
#define MAX 2000
void getOneTest()
{
int N,i,j,oi;
char input[MAX], output[MAX];
scanf("%d",&N);
getchar();
for(i=0;i<N;i++)
input[i]=getchar();
i=0;
j=N-1;
oi=0;
while(i<=j)
{
if(input[i]<input[j])
{
//printf("%d:%c<%d:%c\n",i,input[i],j,input[j]);
output[oi++]=input[i++];
}
else if((input[i]>input[j]))
{
//printf("%d:%c<%d:%c\n",j,input[j],i,input[i]);
output[oi++]=input[j--];
}
else
{
int count=0;
while(input[i]==input[j] &&i<j) //誰先找到最小的下標,就先將誰添加到output後面
{
//printf("%d:%c=%d:%c\n",i,input[i],j,input[j]);
count++;
i++;
j--;
}
if(input[i]<=input[j])
{
//printf("%d:%c<=%d:%c\n",i,input[i],j,input[j]);
j=j+count;
i=i-count;
output[oi++]=input[i++];
}
else if((input[i]>input[j]))
{
//printf("%d:%c<%d:%c\n",j,input[j],i,input[i]);
j=j+count;
i=i-count;
output[oi++]=input[j--];
}
}
}
output[oi]='\0';
printf("%s\n",output);
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
getOneTest();
}
改進版:
#include<stdio.h>
#define MAX 2000
void getOneTest()
{
int N,i,j,oi;
char input[MAX], output[MAX];
scanf("%d",&N);
getchar();
for(i=0;i<N;i++)
input[i]=getchar();
i=0;
j=N-1;
oi=0;
while(i<=j)
{
if(input[i]<input[j])
output[oi++]=input[i++];
else if((input[i]>input[j]))
output[oi++]=input[j--];
else
{
int tmpI=i, tempJ=j;
bool flag=0;
while(input[tmpI]==input[tempJ] &&tmpI<tempJ) //誰先找到最小的下標,就先將誰添加到output後面
{
//printf("%d:%c=%d:%c\n",i,input[i],j,input[j]);
tmpI++;
tempJ--;
}
flag=(input[i]<=input[j]);
if(flag)
output[oi++]=input[i++];
else
output[oi++]=input[j--];
}
}
output[oi]='\0';
printf("%s\n",output);
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
getOneTest();
}