题目大意:T个测试样例,每个测试样例给你一个字符串,该字符串是首尾连接的一个环。问将该字符串从何处断开字典序最小,输出字典序最小的排列。
AC代码1:
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[105];
char S[205];
int main()
{int t;scanf("%d",&t);while(t--){scanf("%s",s);strcpy(S,s);strcat(S,s);//将首尾相连变为线性int len=strlen(s);char ch='Z';int mark[105],index=0;for(int i=0;i<len;i++)//找最小{if(s[i]<ch)ch=s[i];}for(int i=0;i<len;i++)//记录每个最小出现位置if(s[i]==ch)mark[index++]=i;for(int i=1;i<index;i++)/从每个最小开始对比{int j=mark[0],k=mark[i];while(S[k]==S[j])k++,j++;if(S[k]<S[j])mark[0]=mark[i];}for(int i=mark[0];i<len;i++)printf("%c",s[i]);for(int i=0;i<mark[0];i++)printf("%c",s[i]);printf("\n");}return 0;
}
AC代码2(优化):
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[105];
int main()
{int t;scanf("%d",&t);while(t--){scanf("%s",s);int len=strlen(s);int mini=0;for(int i=0;i<len;i++){for(int j=0;j<len;j++){if(s[(mini+j)%len]!=s[(i+j)%len]){if(s[(mini+j)%len]>s[(i+j)%len])mini=i;break;}}}for(int i=0;i<len;i++)printf("%c",s[(mini+i)%len]);printf("\n");}return 0;
}