题目链接:http://codeforces.com/problemset/problem/126/B

题目大意:

多组数据
每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀,并且在S的中间出现过(即非前缀也非后缀)。

分析:

  利用KMP的next数组。
首先next[i]表示该位(不包括)往前数next[i]位恰好构成字符串S的一个前缀,假设字符串长度为len,那next[len]就表示S长为next[len]的后缀正好是S的前缀,恰好就是题目说的公共前后缀,于是想知道S中间有没有这个公共前后缀只要搜一遍next数组,从1~len-1,看有没有等于next[len],如果有就输出S的前next[len]个字符,没有就输出"Just a legend"。
  不过上面的方法存在漏铜,对于有的情况,自然是没问题的;对于没有的情况,就有疏漏:
  对于字符串“abdabsab”,next数组为{-1,0,0,0,1,2,0,1,2},显然是可以的;
  而对于字符串“abfabdabeabfab”,next数组为{-1,0,0,0,1,2,0,1,2,0,1,2,3,4,5},在这个案例里找5当然是找不到的,但确实存在子串“ab”,在开头结尾中间都出现过。在这种情况下,答案如果存在,它必然同时是“abfab”的前缀和后缀,也就是再让“abfab”自己和自己玩一次找公共前后缀得到长度为2,然后在next数组里搜2才行。那也就是说要递归?其实不用,设p = len,令p = next[p],直接在next中查p即可,还查不到就在做一次p = next[p],继续查,直到找到或找不到(p < 0)。这是为什么呢?原因还是“abfab”自己和自己玩,只不过这个“abfab”是开头那个,而p此时正好就是“abfab”再后一位的next值,直接就变成了求子问题,不需要递归。

代码如下:

 #include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
const int maxN = 1e5 + ; string s; void KMP_next(string &T, vector< int > &nxt) {
nxt.resize(T.size() + );
nxt[] = -; int t = -, i = ;
while(i < T.size()) {
( > t || T[i] == T[t]) ? nxt[++i] = ++t : t = nxt[t];
}
} int main(){
while(cin >> s) {
string ans = "";
vector< int > nxt;
KMP_next(s, nxt);
unordered_set< int > si;
rep(i, nxt.size() - ) si.insert(nxt[i]); int p = nxt[nxt.size() - ];
while(p > ) {
if(si.find(p) != si.end()) {
ans = s.substr(, p);
break;
}
p = nxt[p];
} if(ans == "") cout << "Just a legend\n";
else cout << ans << endl;
} return ;
}

CodeForces 126B Password的更多相关文章

  1. Codeforces 126B. Password(KMP,DP)

    Codeforces 126B. Password 题意:一个字符串,找出最长的子串t,它既是前缀又是后缀,还出现在中间.输出t,不存在则输出Just a legend. 思路:利用KMP算法处理出n ...

  2. Codeforces 126B. Password (KMP)

    <题目链接> 题目大意:给定一个字符串,从中找出一个前.中.后缀最长公共子串("中"代表着既不是前缀,也不是后缀的部分). 解题分析:本题依然是利用了KMP中next数 ...

  3. Codeforces 126B Password(Z算法)

    题意 给定一个字符串 \(s\) ,求一个子串 \(t\) 满足 \(t\) 是 \(s\) 的前缀.后缀且在除前缀后缀之外的地方出现过. \(1 \leq |s| \leq 10^6\) 思路 \( ...

  4. 【Codeforces 126B】Password

    [链接] 我是链接,点我呀:) [题意] 给你一个字符串s 让你从中选出来一个字符串t 这个字符串t是s的前缀和后缀 且在除了前缀和后缀之外的中间部位出现过. 且要求t的长度最长. 让你输出这个字符串 ...

  5. codeforces 126B

    Asterix, Obelix and their temporary buddies Suffix and Prefix has finally found the Harmony temple. ...

  6. Codeforces A. Password(KMP的nxt跳转表)

    题目描述: Password time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  7. Codeforces 79D - Password(状压 dp+差分转化)

    Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...

  8. Codeforces 126B(kmp)

    要点 头尾的最长相同只要一个kmp即可得,于是处理中间部分 扫一遍记录一下前缀的每个位置是否存在一个中间串跟它相同,见代码 如果当前没有,接着用Next数组去一找即可 #include <cst ...

  9. 126B Password[扩展kmp学习]

    题目大意 给你一个字符串,求它的一个子串使得这个子串即使前缀又是后缀又出现在不是前缀且不是后缀的地方 分析 扩展kmp就是定义z[i]表示i~n的子串与整个串的最长公共前缀的长度是z[i] 所以这个题 ...

随机推荐

  1. 安装mysql5.6报错问题统计点

    报错1(su进入mysql属组时报错): [root@dbserver ~]# su - mysql Last login: Thu Aug 31 17:20:03 CST 2017 on pts/1 ...

  2. [matlab] 16.多约束非线性规划 ga工具箱解决 [带不等式约束]

    下面举例说明如何运用GA工具箱求解多约束非线性规划问题: function f =fitness(x) f=exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2 ...

  3. C# List去重的三种方法(转)

    三种去重的方法 1.List中的元素实现IEquatabe接口,并提供Equals方法和GetHashCode方法. 2.使用表达式 users.Where((x,i)=>users.FindI ...

  4. HashMap 1.7

    1.关键属性与内部类 1.1属性 使用拉链法解决hash冲突的hash表,hash表里存了多少个元素.数组有多长以及当什么情况下需要扩容是重要的参数. transient Entry<K,V&g ...

  5. ssm框架的整合搭建(二)

    maven简单项目的创建前面已经完成了,下面开始依赖包和配置文件的编写 好好努力每一天!!!!!! 项目结构看这里 1.首先,依赖包pom.xml <project xmlns="ht ...

  6. 【vue】vue +element 搭建项目,要求既支持pc端又支持移动端

    使用场景:有适配pc端改为适配pc端和移动端,使用2套css 代码实现App.vue created: function () { if(document.documentElement.client ...

  7. CF176E Archaeology

    CF176E Archaeology 有一棵 \(n\) 个点的带权树,每个点都是黑色或白色,最初所有点都是白色的.有 \(m\) 个询问: 把点 \(x\) 从白色变成黑色 把点 \(x\) 从黑色 ...

  8. C# GDI+双缓冲技术

    我想有很多搞图形方面的朋友都会用到双缓冲技术的时候,而且有的时候她的确是个头疼的问题.最近我也要用双缓冲技术,程序怎么调试都不合适,当要对图形进行移动时,总是会出现闪烁抖动.在网上找了些资料,说得都不 ...

  9. 基于 Django2 实现邮箱注册登录功能

    1. 开发环境 Python 3.6.5 Django 2.2 2. 项目功能 用户登录 邮箱注册 图形验证码 找回密码 修改密码 用户退出 3. 项目创建 首先创建项目: django-admin ...

  10. python--Numpy and Pandas 笔记01

    博客地址:http://www.cnblogs.com/yudanqu/ 1 import numpy as np import pandas as pd from pandas import Ser ...