hdu 4333 扩展kmp
2015-04-29 10:45
357 查看
题意:题意:给定一个数字<=10^100000,一次将该数的第一位放到放到最后一位,求所有组成的不同的数比原数小的个数,相等的个数,大的个数
扩展kmp入门题
假如有431,则复制为2个,即,431431,
对该字符串和原穿求ekmp求得extend,求得最长公共前缀,3,0,0,3,0,0,extend【1】=3即表示匹配3位则刚好为原串的长度,则相等,extend【2】=0表示并未存在相同前缀,这时就拿3和4比较,假设extend【2】=1,即存在一个相同前缀,那么只需要和第二位比较即可。
总体来说就是避免不必要的比较
扩展kmp入门题
假如有431,则复制为2个,即,431431,
对该字符串和原穿求ekmp求得extend,求得最长公共前缀,3,0,0,3,0,0,extend【1】=3即表示匹配3位则刚好为原串的长度,则相等,extend【2】=0表示并未存在相同前缀,这时就拿3和4比较,假设extend【2】=1,即存在一个相同前缀,那么只需要和第二位比较即可。
总体来说就是避免不必要的比较
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> using namespace std; const int MAXN=2000010; int nextt[MAXN]; int extend[MAXN]; void pre_EKMP(char x[],int m,int nextt[]) { nextt[0]=m; int j=0; while(j+1<m && x[j]==x[j+1])j++; nextt[1]=j; int k=1; for(int i=2;i<m;i++) { int p=nextt[k]+k-1; int L=nextt[i-k]; if(i+L<p+1)nextt[i]=L; else { j=max(0,p-i+1); while(i+j<m && x[i+j]==x[j])j++; nextt[i]=j; k=i; } } } void EKMP(char x[],char y[]) { int n=strlen(y); int m=strlen(x); pre_EKMP(x,m,nextt); int j=0; while(j<n && j<m && x[j]==y[j])j++; extend[0]=j; int k=0; for(int i=1;i<n;i++) { int p=extend[k]+k-1; int L=nextt[i-k]; if(i+L<p+1)extend[i]=L; else { j=max(0,p-i+1); while(i+j<n && j<m && y[i+j]==x[j])j++; extend[i]=j; k=i; } } } void getnextt(char T[],int len) { int j,k; j=0;k=-1; nextt[0]=-1; while(j<len) { if(k==-1 || T[j]==T[k]) nextt[++j]=++k; else k=nextt[k]; } } char str1[MAXN],str2[MAXN]; int main() { #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif int T; int iCase=0; scanf("%d",&T); while(T--) { iCase++; scanf("%s",str1); int len=strlen(str1); strcpy(str2,str1); strcat(str2,str1); EKMP(str1,str2); /*for(int i=0;i<len*2;i++) { printf("%d ",extend[i]); } printf("\n");*/ int cnt1=0,cnt2=0,cnt3=0; for(int i=0;i<len;i++) { if(extend[i]>=len)cnt2++; else { if(str2[i+extend[i]]<str1[extend[i]])cnt1++; else cnt3++; } } getnextt(str1,len); int t=len-nextt[len]; int tol=1; if(len%t==0)tol=len/t; printf("Case %d: %d %d %d\n",iCase,cnt1/tol,cnt2/tol,cnt3/tol); } return 0; }
相关文章推荐
- hdu 4333 扩展kmp+kmp重复字串去重
- hdu 4333 kmp+扩展kmp
- HDU 4333 Revolving Digits [扩展KMP]
- Hdu 4333 Revolving Digits 扩展KMP
- hdu 4333 Revolving Digits (扩展kmp)
- HDU 4333 Revolving Digits 扩展KMP
- hdu 4333(扩展kmp)
- HDU 4333 Revolving Digits(KMP:循环节+扩展KMP)
- HDU 4333 Revolving Digits (扩展KMP)
- hdu 4333(扩展KMP)
- hdu 4333 Revolving Digits 扩展kmp
- 字符串(扩展KMP):HDU 4333 Revolving Digits
- HDU 4333:Revolving Digits KMP+扩展KMP
- 【扩展kmp+最小循环节】HDU 4333 Revolving Digits
- hdu 4333 Revolving Digits 扩展kmp
- HDU 4333 Revolving Digits 扩展KMP
- HDU 4333 Revolving Digits 扩展KMP
- hdu 4333 Revolving Digits (扩展KMP)
- HDU 4333 Revolving Digits(扩展KMP啊)
- HDU 4333 Revolving Digits(扩展kmp)