hdu 4333(扩展KMP)
来源:互联网 发布:西门子840d编程指令 编辑:程序博客网 时间:2024/06/07 00:41
题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个。比如341-->134-->413-->341,所以和原数字相比,比原数字小的有一个,相等的有一个,大的有一个。
分析:经过观察,其实就是求每一位的后缀与自身的最长公共前缀,这个显然可以用扩展kmp处理,但是开始的时候我超时了,后来在网上看到别人把这个串后面再接上本身,以它为主串,然后以自身为模板串进行扩展kmp,这样处理把时间复杂度降到了线性的,最后要注意的一个问题就是如何避免重复了,我们可以用普通的kmp求出此串的最小循环节,如果构成完整的循环,那么我们要算的就是循环节长度的情况了!
#include<stdio.h>#include<string.h>char S[201000],T[100500];int next[200500],extend[200500],len,node;void get_node(){ int i=0,j=-1; next[0]=-1; while(i<len) { if(j==-1||T[i]==T[j]) { i++;j++; next[i]=j; } else j=next[j]; } //最小循环节,如1212 ,最小循环节为2,即长度大于2了以后就开始重复了; node=len-next[len];}void get_next(){ int a,p,k,j,len; int L; len=strlen(T); next[0]=len; a=0; while(a<len-1&&T[a]==T[a+1]) a++; next[1]=a; a=1; for(k=2;k<len;k++) { p=a+next[a]-1; L=next[k-a]; if(k-1+L>=p) { j=p-k+1>0?p-k+1:0; while(j+k<len&&T[j+k]==T[j]) j++; next[k]=j; a=k; } else next[k]=L; }}void get_extend(){ get_next(); int a,p,L,k,j,slen,tlen,len; slen=strlen(S);tlen=strlen(T); len=slen>tlen?tlen:slen; a=0; while(a<len&&S[a]==T[a]) a++; extend[0]=a; a=0; for(k=1;k<slen;k++) { p=a+extend[a]-1; L=next[k-a]; if(k-1+L>=p) { j=p-k+1>0?p-k+1:0; while(j+k<slen&&j<tlen&&S[j+k]==T[j]) j++; extend[k]=j; a=k; } else extend[k]=L; }}void solve(){ printf("%d*",node); int i,num1=0,num2=0,num3=0,flag; if(len%node!=0) node=len; for(i=0;i<node;i++) { if(extend[i]>=len) num2++; else if(S[extend[i]]>S[i+extend[i]]) //小于原串 num1++; else if(S[extend[i]]<S[i+extend[i]]) //大于原串 num3++; } printf("%d %d %d\n",num1,num2,num3);}int main(){ int t,i; scanf("%d",&t); getchar(); for(i=1;i<=t;i++) { scanf("%s",T); strcpy(S,T); strcat(S,T); len=strlen(T); get_node(); get_next(); get_extend(); printf("Case %d: ",i); solve(); } return 0;}
0 0
- hdu 4333 kmp+扩展kmp
- hdu 4333 扩展kmp
- hdu 4333 扩展KMP
- hdu 4333(扩展KMP)
- hdu 4333 扩展KMP
- HDU 4333 扩展KMP
- hdu 4333(扩展KMP)
- HDU 4333:Revolving Digits KMP+扩展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
- 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)
- android notification回传数据(返回数据)
- 自定义字体
- 我开博客了,我的女儿上小学了
- NFS umount 提示 device is busy
- Unable to resolve superclass 解决措施
- hdu 4333(扩展KMP)
- fragment的onCreateOptionMenu()
- LeetCode 63 Minimum Path Sum
- 新浪微博ios客户端 开发流程
- Python演绎的精彩故事(一)
- 二叉树(1)已知某2种排序方式,创建这个二叉树并按第3种方式排序
- 代码添加按钮和按钮监听方法
- RailsCasts15 Fun with Find Conditions find中的查询条件
- leetcode系列(4)Evaluate Reverse Polish Notation