1. 程式人生 > >E - Period HDU-1358

E - Period HDU-1358

ios esp sin period 輸入 eof 是否 說明 ostream

題目大意:

多組。給一個n,輸入長度為n 的串,求:這個串所有存在循環節的前綴,輸出前綴長度和循環次數(不重疊)。

解題思路:

從i=0開始,判斷前綴是不是存在循環節,即(i+1)%(i-next[i]) 是否==0 。註:next[i]值是0或-1的忽略,說明前面不存在任何循環節。(關於循環節解釋的見《KMP 專題知識》)。

參考代碼:

技術分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 char a[1000010];
 5 int next[1000010];
 6 int n;
7 void GetNext() //獲得a數列的next數組 8 { 9 int i=0,k=-1; 10 next[0] = -1; 11 while(i<n){ 12 if(k==-1){ 13 next[i+1] = 0; 14 i++;k++; 15 } 16 else if(a[i]==a[k]){ 17 next[i+1] = k+1; 18 i++;k++; 19 } 20 else
21 k = next[k]; 22 } 23 } 24 void DisRes(int num) 25 { 26 int j; 27 printf("Test case #%d\n",num); 28 for(int i=0;i<=n;i++) 29 { 30 if(next[i]==-1 || next[i]==0) //next[i]是-1或0的忽略,說明之前沒有周期性前綴 31 continue; 32 j = i - next[i]; 33 if(i%j==0
) //能整除,說明存在周期性前綴 34 printf("%d %d\n",i,i/j); //輸出這個前綴的長度和周期數 35 } 36 printf("\n"); 37 } 38 int main() 39 { 40 int num = 0; 41 while(scanf("%d",&n)!=EOF) 42 { 43 if(n==0) break; 44 scanf("%s",a); 45 GetNext(); //獲得next[]數組 46 DisRes(++num); //輸出結果 47 } 48 return 0; 49 }
這個回頭自己寫過

E - Period HDU-1358