Theme Section HDU - 4763(些许暴力)

题意:

  求出最长公共前后缀 不能重叠  而且 这个前后缀 在串的中间也要出现一次

解析:

  再明确一次next数组的意思:完全匹配的最长前后缀长度

   求一遍next 然后暴力枚举就好了

  

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1e6+10, INF = 0x7fffffff;
int nex[maxn];

void get_next(char *s)
{
    int len = strlen(s);
    int j = 0, k = -1;
    nex[0] = -1;
    while(j < len)
    {
        if(k == -1 || s[j] == s[k])
            nex[++j] = ++k;
        else
            k = nex[k];
    }
}

int kmp(char *s, char *t, int len1, int len2) //串1  串2  串1的长度  串2的长度
{
    int i, j = 0;
    if(len1 == 1 && len2 == 1)
    {
        if(s[0] == t[0])
            return true;
        else
            return false;
    }
    for(int i=0; i<len1; i++)
    {
        while(j > 0 && s[i] != t[j])
            j = nex[j];
        if(s[i] == t[j])
            j++;
        if(j == len2)
            return true;
    }
}

char s[maxn];
char s2[maxn];
int main()
{
    int T;
    rd(T);
    while(T--)
    {
        rs(s);
        get_next(s);
        int len = strlen(s);
        if(!nex[len]){
            cout<< "0" <<endl;
        }
        else
        {
            int tmp = nex[len];
            while(tmp)
            {
                if(tmp*3 > len) //如果当前长度大于三倍 那么就用次长来匹配
                {
                    tmp = nex[tmp];
                    continue;
                }
                for(int i=0; i<tmp; i++)    //暴力取出那段子串
                    s2[i] = s[i];
                if(kmp(s+tmp, s2, len - 2*tmp, tmp))
                {
                    cout<< tmp <<endl;
                    break;
                }
                tmp = nex[tmp];
            }
        }
    }

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9486000.html