Codeforces 126B(Password) (KMP)

题目链接:传送门

题目描述:

      给你一串字符串S,要你找出它的最长子串t,满足这个t既是S的前缀和后缀,也要在串S的中间位置出现过。如果没有,输出“Just a legend”,否则输出这个子串。

题目分析:

      遇到这题时,刚学完后缀数组,又有后缀出现,就以为是后缀数组了。然后看了下时间1e6,时间刚刚好。然后就高高兴兴的去打了出来,可能常数太大了吧,T了。后来,听大佬讲是KMP,嗯。。。。。。。我还是太菜了。好吧,这题考的是KMP种next数组的运用,先用vis数组把next数组的值记录一遍(除了最后一个),然后用一个while循环看vis[next[i]].如果非零,答案的长度就是next[i]了,否则,i=next[i].

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int len, knext[1000006], vis[1000006] = {0};
void KMP(){
    len = s.length();
    int i, j;
    j = -1, i = 0;
    knext[0] = -1;
    while(i<len){
        if(j == -1 || s[i] == s[j]) knext[++i] = ++j;
        else j = knext[j];
    }
    knext[0] = 0;
    for(i=0;i<len;++i) vis[knext[i]]++;
    int flag = 0;
    i = len;
    while(knext[i]){
        if(vis[knext[i]]){
            for(j=0;j<knext[i];++j) printf("%c", s[j]);
            printf("\n");
            flag = 1;
            break;
        }
        else i = knext[i];
    }
    if(!flag) cout << "Just a legend" << endl;
}
int main()
{
    cin >> s;
    KMP();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41100093/article/details/86597895