这个题我想到要用kmp找到循环节;
但是后面的我就不会做了;
看到题解才知道是字符串的最小表示;
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 100005 using namespace std; char s[maxn*2]; int next[maxn]; void kmp(int n) { int j=0; for(int i=2;i<=n;i++) { while(j>0&&s[i]!=s[j+1])j=next[j]; if(s[i]==s[j+1])++j; next[i]=j; } } void MinimumRepresentation(int n) { int i=1,j=2,k=0; while(1) { if(i==j)j++; else if(s[j]=='0')j++; else if(s[i]=='0')i++; else if(s[i+k]==s[j+k])k++; else if(s[i+k]<s[j+k]) { if(s[i+k]=='0')j=j+k; else j=j+k+1; k=0; } else { if(s[j+k]=='0')i=i+k; else i=i+k+1; k=0; } if(i>n||j>n||k>=n) break; } int t=i<=n?i:j; for(int i=t;i<t+n;i++) putchar(s[i]); puts(""); } int main() { //freopen("test0.in","r",stdin); int t,n; scanf("%d",&t); while(t--) { scanf("%s",s+1); n=strlen(s+1); bool flag=0; for(int i=1;i<=n;i++) if(s[i]!='0')flag=1; if(flag==0){printf("1%s ",s+1);continue;} kmp(n); int m=n-next[n]; for(int i=m+1;i<=(2*m);i++) s[i]=s[i-m]; MinimumRepresentation(m); } return 0; }