CodeForces 126B Password 【kmp】

来源:互联网 发布:手机相片制作软件 编辑:程序博客网 时间:2024/06/06 14:05

题目:点击打开链接

题意:给出一个字符串,求出最长相同的的前缀子串和后缀子串,使得字符串中也存在该子串(不包括前缀子串和后缀子串)。

思路:显然先将字符串处理出next数组,由于next数组保存的是最长公共前后缀长度减一(即要跳转的那一位),所以字符串最后一位字符存的是大于等于满足条件的子串长度,然后要找到中间的子串,从后往前扫一遍字符串直到最长前缀,若发现next值等于最后一个字符的next值,则该值可能是最长长度,先记录下来,然后观察最后一个字符跳转的位置是否能再次跳转,若可以,则继续往前扫,若某位的next值等于最后一个字符跳转的那个位置的next值,则说明存在相同后缀,记录下其next值,最后综上用最大的next值表示答案子串的长度减一,输出前缀子串即可。

代码:

#include <stdio.h>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <set>#include <vector>#include <map>#define PR pair<int,int>#define MP make_pair#define fi first#define se second#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define sqr(x) ((x)*(x))#define ll long long#define ull unsigned __int64const ll INF = 1e18;const int inf=0x3f3f3f3f;const int M=200010;const int N=1000100;const int MOD=10007;const double eps=1e-10;const double pi=acos(-1.0);using namespace std;char a[N];int n,nxt[N];int main(){    int i,j;    scanf("%s",a);    n=strlen(a);    nxt[0]=-1;    for(i=1;i<n;i++)    {        j=nxt[i-1];        while(j>=0&&a[i]!=a[j+1]) j=nxt[j];        nxt[i]=a[i]==a[j+1]?j+1:-1;    }    if(nxt[n-1]==-1) {puts("Just a legend");return 0;}    int ok=0,ans=0;    for(i=n-2;i>nxt[n-1];i--)    {        if(nxt[i]==nxt[n-1]) ok=1,ans=nxt[n-1];    }    if(nxt[nxt[n-1]]!=-1)    {        for(i=nxt[n-1];i>nxt[nxt[n-1]];i--)        {            if(nxt[i]==nxt[nxt[n-1]]) ok=1,ans=max(ans,nxt[nxt[n-1]]);        }    }    if(ok==0) puts("Just a legend");    else    {        for(i=0;i<=ans;i++) printf("%c",a[i]);puts("");    }}


0 0
原创粉丝点击