题目大意:
给你一个长为l的字符串s,求它的最小表示法的最小起始位置。
最小表示法:将原字符串看成循环串,从某处开始的字典序最小的串。
简单题解:
参见2003周源论文《浅析“最小表示法”思想 在字符串循环同构问题中的应用》。
初始化两个指针i=0,j=1。
依次向后匹配,若失配,则将失配字符较大的指针移到失配字符之后。
我的代码:
1 /* 2 ID:t-x.h1 3 LANG:C++ 4 TASK:hidden 5 */ 6 #include<cstdio> 7 #define min(x,y) ((x)<(y)?(x):(y)) 8 FILE *fi=fopen("hidden.in","r"),*fo=fopen("hidden.out","w"); 9 const int MAXl=100000+9; 10 char s[MAXl]; 11 int main() 12 { 13 int l,i,j,k,ti,tj; 14 fscanf(fi,"%d",&l); 15 for(i=0;i<l;++i) 16 { 17 s[i]=fgetc(fi); 18 if(s[i]<'a' || s[i]>'z') 19 --i; 20 } 21 for(i=0,j=1,k=0;i<l && k<l && j<l;) 22 { 23 ti=(i+k)%l,tj=(j+k)%l; 24 if(s[ti]==s[tj]) 25 ++k; 26 else 27 { 28 if(s[ti]>s[tj]) 29 i+=k+1; 30 else 31 j+=k+1; 32 k=0; 33 if(i==j) 34 ++j; 35 } 36 } 37 fprintf(fo,"%d\n",i<j?i:j); 38 fclose(fi); 39 fclose(fo); 40 return 0; 41 }