题解 CF126B 【Password】

第一遍读完这道题,这不就是个裸的KMP板子吗,然后迅速打出了KMP,发现并过不了样例2,于是又仔细读了一下题,发现读漏了一个条件,即需要在中间也出现过,因为我们知道,KMP中的next数组存的是相同的前缀和后缀的长度,那么只需要找在中间出现过前缀长度,并标记一下就行了,最后在匹配的时候多判断一下。

详见代码

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e6 + 5;

string s;
int net[N], num[N];
bool is[N];

int main()
{
    cin >> s;
    for (int i = 1, j = 0; s[i]; i++)
    {
        while (j && s[i] != s[j])
            j = net[j - 1];
        if (s[i] == s[j])
            j++;
        net[i] = j;
    }//求next
    int len = s.length();
    for (int i = 1, j = 0; i < len - 1; i++)
    {
        while (j && s[i] != s[j])
            j = net[j - 1];
        if (s[i] == s[j])
            j++;
        is[j] = true;
    }//找出中间出现过的前缀的长度
    int j = 0;
    for (int i = 0; i < len; i++)
    {
        while (j && s[i] != s[j])
            j = net[j - 1];
        if (s[i] == s[j])
            j++;
        while (j && !is[j])
            j = net[j - 1];//判断是否在中间出现过
    }//匹配
    if (!j)
        cout << "Just a legend";
    else
        for (int i = 0; i < j; i++)
            cout << s[i];
    return 0;
}
posted @ 2020-12-29 10:55  DSHUAIB  阅读(90)  评论(0)    收藏  举报