Problem - 126B - Codeforces
Asterix、Obelix和他们的临时伙伴Suffix和Prefix终于找到了和谐寺。然而,它的门被牢牢地锁住了,即使是Obelix也没能打开它们。
过了一会儿,他们发现在寺庙大门下面的一块岩石上刻着一个字符串。亚力认为那是打开神庙的密码,于是大声念出这根弦。然而,什么也没有发生。然后,Asterix认为密码是字符串s的某个子串t。
前缀认为子串t是字符串s的开头;后缀认为子串t应该是字符串s的结尾;而Obelix认为t应该位于字符串s的某个地方,也就是说,t既不是它的开头,也不是它的结尾。
Asterix选择了子串t,以取悦他的所有同伴。此外,在所有可接受的变体中,Asterix选择了最长的一个(因为Asterix喜欢长字符串)。当Asterix大声读出子串t的时候,神庙的门就打开了。
找到子串t,或者确定这样的子串不存在,上面所写的只是一个美好的传说而已。
输入
给你一个字符串s,其长度可以从1到106(包括)不等,由小的拉丁字母组成。
输出
打印字符串t。如果不存在合适的t字符串,则打印 "Just a legend",不加引号。
例子
inputCopy
fixprefixsuffix
outputCopy
固定
输入复制
abcdabc
输出拷贝
Just a legend
题解:
给定一个字符串,找出其中一个最长的子串,使得这个子串既是前缀又是后缀又在中间出现
是不是很像kmp的next的数组
next数组定义为0到当前的最长相同前缀与后缀的长度(不包括当前i本身)
kmp处理完字符串后我们可以得到一个next数组
先标记1~n-1的出现过的ne数组
我们从ne[n]开始(注意是n,未被标记)
t = ne[n]代表目前整个s串中为这个字符串的最长的相同前缀与后缀的长度
然后循环往前遍历
t = ne[t],如果t被标记过说明存在
重点说明t = ne[t]
t代表目前t之前0~t-1字符串的最长的相同前缀与后缀的长度
这个t肯定是如果t存在,由于前面的ne[t]是由ne[n]转变过来的,字符串后面的后缀也相等
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
using namespace std;
#define int long long
char s[1000050];
int ne[1000050];
int p[1000050];
int n;
void kmp()
{
int i = 0,j = -1;
ne[0] = -1;
while(i < n)
{
if(j == -1||s[j] == s[i])
{
j++;
i++;
ne[i] = j;
}
else
{
j = ne[j];
}
}
for(int i = 1;i < n;i++)
{
p[ne[i]]++;
}
}
void solve()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> s;
n = strlen(s);
kmp();
int t = ne[n];
while(t)
{
if(p[t])
{
for(int i = 0;i < t;i++)
{
cout<<s[i];
}
return ;
}
t = ne[t];
}
cout<<"Just a legend";
}
signed main()
{
int t = 1;
// cin >> t;
while(t--)
{
solve();
}
}