FZU1901(Next数组的应用)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1901
题意:求某个前缀,可以使得前缀和剩下部分能够一一对应,可以是原串。
题解:Next数组的应用,首先 t=Next[len] 的意义是(假设1-t意思是前面t个字符):s[1....t]=s[len-t,len](后面t个字符) 那么,此时len-t的含义就是,把相同部分(前面t个)+不相同部分(去掉前t个和后t个部分)作为前缀则满足题意,所以,只要不断向下找Next的值,则可以求的每一个前缀,直到Next的值为0.
小知识点:k = len-Next[len] 且 len % k == 0 且 Next[len]!=0 则k为len长度下的最小循环节
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=1000000+50; 7 char s[maxn]; 8 int Next[maxn]; 9 int sum[maxn]; 10 void getNext(int len) 11 { 12 int i=0,j=-1; 13 Next[0]=-1; 14 while(i<len) 15 { 16 if(j==-1||s[i]==s[j]) 17 i++,j++,Next[i] = j; 18 else 19 j = Next[j]; 20 } 21 } 22 int main() 23 { 24 int test; 25 cin>>test; 26 int temp=1; 27 while(test--) 28 { 29 scanf("%s",s); 30 int len=strlen(s); 31 getNext(len); 32 int j=Next[len]; 33 int sum1=0; 34 while(j) 35 { 36 sum[sum1++]=len-j; 37 j=Next[j]; 38 } 39 sum[sum1++]=len; 40 printf("Case #%d: %d\n",temp++,sum1); 41 for(int i=0;i<sum1-1;i++) 42 printf("%d ",sum[i]); 43 printf("%d\n",sum[sum1-1]); 44 } 45 }
浙公网安备 33010602011771号