首页 > 代码库 > hdu 4333 不错的EKMP+KMP
hdu 4333 不错的EKMP+KMP
题意就不说了
把串头尾相接 当做文本串 把原串作模式串 进行EKMP 对每个i 若果extand【i】》=len则相等 否则比较下一位即可判断是大于还是小于 对于题意所说的不同的数 就是让你去判断原串是不是回文串 这就得用到KMP里面的next数组了 具体看代码: 最后用得出来的去除以循环次数就行了
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; char str1[200010],str2[200010]; int next[100010],extand[200010],knext[100010]; int kmpnext(char str[],int len) { memset(knext,0,sizeof(knext)); knext[0]=-1; int j=0,k=-1; while(j<len) { if(k==-1||str[j]==str[k]) { ++j; ++k; knext[j]=k; } else k=knext[k]; } return 0; } int get_next(char str[],int len) { memset(next,0,sizeof(next)); next[0]=len; int a=0; while(a<len&&str[a]==str[a+1]) a++; next[1]=a; a=1; for(int i=2;i<len;i++) { int p=a+next[a]-1; int L=next[i-a]; if(L+i-1>=p) { int j=p-i+1>0?p-i+1:0; while(i+j<len&&str[i+j]==str[j]) j++; next[i]=j; a=i; } else next[i]=L; } return 0; } int EKMP(char str1[],char str2[]) { int len=strlen(str2); get_next(str2,len); int a=0; while(a<len&&str1[a]==str2[a]) a++; extand[0]=a; a=0; for(int i=1;i<2*len;i++) { int p=a+extand[a]-1; int L=next[i-a]; if(L+i-1>=p) { int j=p-i+1>0?p-i+1:0; while(i+j<2*len&&j<len&&str1[i+j]==str2[j]) j++; extand[i]=j; a=i; } else extand[i]=L; } return 0; } int main() { int T,i,j,d=1,k; scanf("%d",&T); while(T--) { scanf("%s",str1); int len=strlen(str1); strcpy(str2,str1); strcat(str1,str2); kmpnext(str2,len); int t=len-knext[len]; k=1; if(len%t==0) k=len/t; EKMP(str1,str2); int Min=0,Max=0,equal=0; for(i=0;i<len;i++) { if(extand[i]>=len) equal++; else { if(str1[i+extand[i]]>str1[extand[i]]) Max++; else Min++; } } printf("Case %d: %d %d %d\n",d++,Min/k,equal/k,Max/k); } return 0; }
hdu 4333 不错的EKMP+KMP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。