仔细看 这个 点击打开链接 好好理解 next数组的含义
POJ 2406 求最小的 循环节长度
#include<iostream>
#include<string.h>
#include<cstring>
#include<stdio.h>
using namespace std;
char b[1000010];
int next[1000010];
int m,n;
void g_next(int m){
int j=-1,i=0;
next[0]=-1;
while(i<m){
if(j==-1||b[j]==b[i]){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
}
int main(){
while(scanf("%s",b)!=EOF){
if(b[0]=='.') break;
m=strlen(b);
g_next(m);
if(m%(m-next[m])==0){
printf("%d\n",m/(m-next[m]));
}
else{
cout<<"1"<<endl;
}
}
}
POJ 1961
#include<iostream>
#include<string.h>
#include<cstring>
#include<stdio.h>
using namespace std;
char b[1000010];
int next[1000010];
int m,n;
void g_next(int m){
int j=-1,i=0;
next[0]=-1;
while(i<m){
if(j==-1||b[j]==b[i]){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
}
int main(){
int t=1;
int k;
while(cin>>k){
if(!k) break;
cin>>b;
m=strlen(b);
g_next(m);
cout<<"Test case #"<<t<<endl;
for(int j=1;j<=k;j++){
int l=j-next[j];
if(l!=j&&j%l==0){
cout<<j<<" "<<j/l<<endl;;
}
}
t++;
cout<<endl;
}
return 0;
}
POJ 2752
好好理解 next
#include<iostream>
#include<string.h>
#include<cstring>
#include<stdio.h>
using namespace std;
char b[40000010];
int next[40000010];
int ans[40000001];
int m,n;
void g_next(int m){
int j=-1,i=0;
next[0]=-1;
while(i<m){
if(j==-1||b[j]==b[i]){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
}
int main(){
while(cin>>b){
m=strlen(b);
g_next(m);
int k=0;
while(m!=-1&&m!=0){
ans[k++]=m; //寻找前缀和后缀相同
m=next[m];
}
for(int j=k-1;j>=0;j--){
cout<<ans[j]<<" ";
}
cout<<endl;
}
return 0;
}