https://cn.vjudge.net/problem/POJ-2406
上面是比赛链接。
题目意思很明确,问最多是多少个子串连接而成的?
这个需要用到KMP,很好的理解KMP的Next数组。Next数组里面存了当匹配失败时应该跳到的位置,所以,最后一个数的部分匹配值 ,判断 n%(n-Next[n])为0 就可以。
Next[len]代表某位字符的部分匹配值,根据部分匹配值可以得到周期为:长度-Next[n]。在最后判断能否被长度整除即可.
#include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <set> #include <map> #include <list> #include <queue> #include <deque> #include <stack> #include <string> #include <vector> #include <iostream> #include <algorithm> #include <stdlib.h> #include <time.h> using namespace std; typedef long long LL; const int INF=2e9+1e8; const int MOD=1e9+7; const int MAXSIZE=1e6+5; const double eps=0.0000000001; void fre() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); } #define memst(a,b) memset(a,b,sizeof(a)) #define fr(i,a,n) for(int i=a;i<n;i++) int Next[MAXSIZE]; char str[MAXSIZE]; void getNext(int n) { int i=0,j=-1; Next[0]=-1; while(i<n) { if(j==-1||str[i]==str[j]) { j++,i++; Next[i]=j; } else j=Next[j]; } } int main(int argc,char *argv[]) { while(scanf("%s",str)!=EOF) { if(str[0]=='.') break; int len=strlen(str); //printf("len=%d ",len); getNext(len); // for(int i=0;i<=len;i++) // { // printf("%d ",Next[i]); // } // printf(" "); if(len%(len-Next[len])==0) printf("%d ",len/(len-Next[len])); else printf("1 "); } return 0; } /**************************************************/ /** Copyright Notice **/ /** writer: wurong **/ /** school: nyist **/ /** blog : http://blog.csdn.net/wr_technology **/ /**************************************************/