最大最小表示法
目的:已知一个串S,求S的循环的同构字符串S'中字典序最大/最小的一个,输出其位置,place∈[0,n-1]
设S=bcad,S'=bcad,cadb,adbc,dbca,最小表示的S'是adbc,位置是2,最大表示的S'是dbca,位置是3
时间复杂度:O(n)
自用模板:
int get_minstring(char *s) //最小表示法 { int len=strlen(s); int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if(t==0) k++; else { if(t>0) i=i+k+1; else j=j+k+1; if(i==j) j++; k=0; } } return min(i,j); } int get_maxstring(char *s) //最大表示法 { int len=strlen(s); int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if(t==0) k++; else { if(t>0) j=j+k+1; else i=i+k+1; if(i==j) j++; k=0; } } return min(i,j); }
hdu3374,求最大最小表示法的位置+出现的次数,出现次数=循环节,kmp即可
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; int get_minstring(char *s) { int len=strlen(s); int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if(t==0)k++; else { if(t>0)i+=k+1; else j+=k+1; if(i==j)j++; k=0; } } return min(i,j); } int get_maxstring(char *s) { int len=strlen(s); int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if(t==0)k++; else { if(t>0)j+=k+1; else i+=k+1; if(i==j)j++; k=0; } } return min(i,j); } int Next[maxn]; void get_next(char *p) { int m=strlen(p); Next[0]=Next[1]=0; for(int i=1;i<m;i++) { int j=Next[i]; while(j&&p[i]!=p[j])j=Next[j]; Next[i+1]=p[i]==p[j]?j+1:0; } } int main() { char s[maxn]; while(scanf("%s",s)!=EOF) { int l=get_minstring(s); int r=get_maxstring(s); get_next(s); int len=strlen(s); int cal=len-Next[len],times=len/cal; printf("%d %d %d %d\n",l+1,times,r+1,times); } return 0; }
hdu2609,n个01串(长度不超100),如果两串是同构字符串则为同一种,求有几种串
#include<bits/stdc++.h> using namespace std; const int maxn=110; int get_minstring(string s) { int len=s.size(); int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if(t==0)k++; else { if(t>0)i+=k+1; else j+=k+1; if(i==j)j++; k=0; } } return min(i,j); } int main() { int n; while(scanf("%d",&n)!=EOF) { map<string,int>mp; int ans=0; for(int i=0;i<n;i++) { string s1; cin>>s1; int l=get_minstring(s1),len=s1.size(); string s2=s1.substr(l,len-l)+s1.substr(0,l); if(mp[s2]==0)ans++; mp[s2]++; } printf("%d\n",ans); } return 0; }
...