Password CodeForces - 126B【KMP深度理解題】

KMP學習更新日誌

題目鏈接


題意:

  給你一串字符串,我們要找到這樣的一串子字符串,讓他滿足既是前綴又是後綴,並且還在中間出現過的最長子字符串,如果沒有就輸出題目給的那一串東西。


  因爲我們知道前綴的next[]開始都是從0開始的,所以我們可以不考慮它,然後從後綴看,後綴的next[]不能爲0,因爲那樣就說明不存在這樣的答案,所以,我們知道的是後綴肯定在不爲0的情況下才有解的可能,接下來,我們向前看,看看中間的字符串是否有等next[]值的點,有的話,那麼它一定是最優解,那麼,我們怎麼確定是否存在呢?用到了STL中的set來處理這樣的問題,我們把1~len-1的所有next[]解的值都存進去,這裏不存終點的是因爲我們利用的是終點的值來推的,所以不能存終點,然後我們從終點開始向前回溯,遇到set.count()存在的話就是可行解,輸出就是了,不然搜完後還是沒有就直接輸出題目中給出的那組。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=1e6+5;
char a[maxN];
int len, nex[maxN];
set<int> st;
void cal_next()
{
    nex[0] = nex[1] = 0;
    int k = 0;
    for(int i=2; i<=len; i++)
    {
        while(k>0 && a[k+1]!=a[i]) k=nex[k];
        if(a[k+1] == a[i]) k++;
        nex[i]=k;
    }
}
int main()
{
    while(scanf("%s", a+1)!=EOF)
    {
        getchar();
        len=(int)strlen(a+1);
        cal_next();
        st.clear();
        int tmp = nex[len];
        for(int i=1; i<len; i++) st.insert(nex[i]);
        bool flag=false;
        while(tmp>0)
        {
            if(st.count(tmp))
            {
                flag=true;
                for(int i=1; i<=tmp; i++) printf("%c", a[i]);
                printf("\n");
                break;
            }
            tmp=nex[tmp];
        }
        if(!flag) printf("Just a legend\n");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章