符串的最小循环节 kmp Cyclic Nacklace

来源:互联网 发布:网络摄像头ip地址查询 编辑:程序博客网 时间:2024/05/23 18:33
思路:kmp+字符串的最小循环节问题

分析:
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<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<queue>#include<map>#include<stack>#include<vector>#define LL long long#define MAXN 100010using namespace std;int len;char ss[1000007];int f[1000007];typedef pair<int,int> P;template <class T>inline bool rd(T &ret) {    char c; int sgn;    if (c = getchar(), c == EOF) return 0;    while (c != '-' && (c<'0' || c>'9')) c = getchar();    sgn = (c == '-') ? -1 : 1;    ret = (c == '-') ? 0 : (c - '0');    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');    ret *= sgn;    return 1;}template <class T>inline void pt(T x) {    if (x < 0) {        putchar('-');        x = -x;    }    if (x > 9) pt(x / 10);    putchar(x % 10 + '0');}void getfail(){    f[0]=0;    f[1]=0;    for(int i=1;i<len;i++)    {        int j=f[i];        while(j&&ss[i]!=ss[j]) j=f[j];        f[i+1]=ss[i]==ss[j]?j+1:0;    }}int main(){    //freopen("in.txt","r",stdin);    int t,cir=0 ;    cin>>t;    while(t--)    {        scanf("%s",ss);        len=strlen(ss);        getfail();        cir=len-f[len];        //cout<<"cir"<<cir<<endl;        if(cir==len) cout<<len<<endl;        else if(len%cir==0) cout<<0<<endl;        else            cout<<cir-(len-(len/cir)*cir)<<endl;    }    return 0;}


0 0
原创粉丝点击