HDU 3746 Cyclic Nacklace(KMP:補齊迴圈節)
CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of "HDU CakeMan", he wants to sell some little things to make money. Of course, this is not an easy task. |
此題補齊迴圈節的幾種判斷方法
如果f[m]=0那麼要補m個
如果m%f[m]==0那麼已經存在迴圈節
否則需要補齊:
分析:
最小迴圈節長度是m-f[m],那麼還要補充m-m%f[m];
1 題目要求的是給定一個字串,問我們還需要新增幾個字元可以構成一個由n個迴圈節組成的字串。
2 可知我們應該先求出字串的最小迴圈節的長度:假設字串的長度為len,那麼最小的迴圈節就是cir = len-next[len] ;
如果有len%cir == 0,那麼這個字串就是已經是完美的字串,不用新增任何字元;
如果不是完美的那麼需要新增的字元數就是cir - (len-(len/cir)*cir)),相當與需要在最後一個迴圈節上面新增幾個。
3 如果cir = 1,說明字串只有一種字元例如“aaa” ;
如果cir = m說明最小的迴圈節長度為m,那麼至少還需m個;
如果m%cir == 0,說明已經不用添加了。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXM=100000+100; int f[MAXM],m; char P[MAXM]; void getFail(char *P,int *f) { f[0]=f[1]=0; for(int i=1;i<m;i++) { int j=f[i]; while(j && P[i]!=P[j]) j=f[j]; f[i+1]= (P[i]==P[j])?j+1:0; } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",P); m=strlen(P); getFail(P,f);//求next陣列; if(f[m]==0) { printf("%d\n",m); continue; }//當f[m]=0時,輸出它的長度; if(m%(m-f[m])==0) printf("0\n");//如果存在迴圈節 else { int len1=m-f[m];// printf("%d\n",len1-m%len1); } } return 0; }