hdu 4333 Revolving Digits 拓展kmp算法

来源:互联网 发布:安卓慢镜头拍摄软件 编辑:程序博客网 时间:2024/05/21 09:38

题意:给定一个数字<=10^100000,一次将该数的第一位放到放到最后一位,求所有组成的不同的数比原数小的个数,相等的个数,大的个数


分析:看了一晚上的拓展kmp,感觉这东西挺神的不过用的不大多。

基本上是裸的拓展kmp。把原串接到自己后面组成一个新串,把next数组求出来后,若next[i]>=len则该数与原来的数相等,不然就判断后一位的大小就好了。

唉hdu不知为毛交不了,拿网上的AC程序来对拍,没拍出错来,于是默认AC……


代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define N 200005using namespace std;int next[N],extend[N],len;char s[N],t[N];void getnext(){next[1]=len*2;int a=1;while (t[a+1]==t[a]&&a<len*2) a++;next[2]=a-1;a=2;int i=3;while (i<=len*2){int p=a+next[a]-1,L=next[i-a+1];if (i+L-1>=p){int j=max(p-i+1,0);while (i+j<=len*2&&t[j+i]==t[j+1]) j++;next[i]=j;a=i;}else next[i]=L;i++;}}void getextend(){int a=0;while (a<len&&s[a+1]==t[a+1]) a++;extend[1]=a;a=1;int i=2;while (i<=len){int p=a+next[a]-1,L=next[i-a+1];if (i+L-1>=p){int j=max(p-i+1,0);while (i+j<=len&&t[j+i]==t[j+1]) j++;next[i]=j;a=i;}else next[i]=L;i++;}}int main(){int w;scanf("%d",&w);for (int i=1;i<=w;i++){scanf("%s",s);len=strlen(s);for (int j=len;j>=1;j--){s[j]=s[j-1];t[j]=s[j];t[j+len]=t[j];}getnext();getextend();int ans1=0,ans2=0,ans3=0;for (int j=1;j<=len;j++)if (next[j]>=len) ans2++;else if (t[j+next[j]]<t[next[j]+1]) ans1++;else ans3++;printf("Case %d: %d %d %d\n",i,ans1,ans2,ans3);}return 0;}


0 0
原创粉丝点击