模板 最小表示法
字符串的最小表示在hash 等领域有应用
模板代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using std::min; 5 char str[100000]; 6 int main() 7 { 8 scanf("%s",str); 9 int len=strlen(str); 10 int i=0,j=1,k=0; 11 while(i<len&&j<len&&k<len) 12 { 13 int t=str[(i+k)%len]-str[(j+k)%len]; 14 if(!t) 15 k++; 16 else{ 17 if(t>0) 18 i+=k+1; 19 else 20 j+=k+1; 21 if(i==j) 22 j++; 23 k=0; 24 } 25 } 26 int sta=min(i,j); 27 for(int i=sta;i<len;i++) 28 putchar(str[i]); 29 for(int i=0;i<sta;i++) 30 putchar(str[i]); 31 putchar('\n'); 32 return 0; 33 }
最小表示法裸上。
双模hash一下存map里
代码:
1 #include<map> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using std::map; 6 using std::min; 7 using std::swap; 8 using std::pair; 9 using std::make_pair; 10 typedef unsigned long long lnt; 11 const lnt sd1=18321973; 12 const lnt sd2=32984721; 13 map<pair<lnt,lnt>,bool>M; 14 char str[10000]; 15 lnt tmp[100000]; 16 int n; 17 int main() 18 { 19 while(scanf("%d",&n)!=EOF) 20 { 21 M.clear(); 22 int cnt=0; 23 for(int i=1;i<=n;i++) 24 { 25 scanf("%s",str+1); 26 int len=strlen(str+1); 27 int a1=1; 28 int a2=2; 29 int ln=0; 30 while(a1<=len&&a2<=len&&ln<len) 31 { 32 int t=str[(a1+ln-1)%len+1]-str[(a2+ln-1)%len+1]; 33 if(!t) 34 ln++; 35 else{ 36 if(t<0) 37 a1+=ln+1; 38 else 39 a2+=ln+1; 40 if(a1==a2) 41 a2++; 42 ln=0; 43 } 44 } 45 int sta=min(a1,a2); 46 int l=0; 47 for(int i=sta;i<=len;i++) 48 tmp[++l]=str[i]; 49 for(int i=1;i<sta;i++) 50 tmp[++l]=str[i]; 51 lnt ax=0,ay=0; 52 for(int i=1;i<=len;i++) 53 { 54 ax=ax*sd1+tmp[i]; 55 ay=ay*sd2+tmp[i]; 56 } 57 if(ax>ay) 58 swap(ax,ay); 59 pair<lnt,lnt>x=make_pair(ax,ay); 60 if(M.find(x)==M.end()) 61 cnt++; 62 M[x]=true; 63 } 64 printf("%d\n",cnt); 65 } 66 return 0; 67 }