HDU3746 KMP相同公共前缀和公共后缀的最大长度应用及KMP

来源:互联网 发布:新闻的作用和意义知乎 编辑:程序博客网 时间:2024/05/17 15:35

题目大意:在字符串后面最少添加多少个字符可以实现两次循环。

思路:前面有提到过字符串相同公共前缀和公共后缀的最大长度。他的求法和next求法类似,次数也用next数组命名。求得相同前缀和的后缀的最长长度后,进行判断。

如果next[last] = 0,则说明这个字符在前面只出现了一次,必须在结尾加len个字符。若果next[last]刚好可以被字符创长度整除,说明前面已经构成了循环,所以添加0个就好。

最后一种看代码就懂了。


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 100005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define ULL long longconst long long INF=0x3fffffff;char a[maxn];int Next[maxn];//ofstream  ofile;int main(){    int n , t;    cin  >> t;    while(t--)    {        scanf("%s" , a+1);        int m = strlen(a+1);        mem(Next , 0);        int num = 0;        for(int i = 2 ; i <= m ; i ++)        {            while(num > 0 && a[num + 1] != a[i]) num = Next[num];            if(a[num+1] == a[i]) num++;            Next[i] = num;        }        int min_c = m - Next[m];        if(min_c == m) printf("%d\n" , m);        else if(m % min_c == 0) printf("0\n");        else printf("%d\n" , min_c - m % min_c);    }    return 0;}


0 0