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

大意:给一个字符串,问最长的既是前缀又是后缀又是中缀(这里指在内部出现)的子串。

我自己的做法是用KMP的next数组,对所有既是前缀又是中缀的位置计数,再从next[n]开始走next,也即枚举所有既是前缀又是后缀的子串,看cnt[i]是否大于0,如果大于0则说明作为中缀出现过(也即有大于i的某个位置的next为i)

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set> using namespace std; const int N=1e6+;
char s[N];
int next[N];
int cnt[N];
void getNext(char *word,int n=){
n=(n==)?strlen(word):n;
memset(next,,sizeof(next));
int i,j;
for (i=;i<n;i++){
j=i;
while (j){
j=next[j];
if (word[i]==word[j]){
next[i+]=j+;
break;
}
}
}
}
int main () {
scanf("%s",s);
int n=strlen(s);
getNext(s,n);
for (int i=;i<n;i++)
cnt[next[i]]++;
if (next[n]==)
puts("Just a legend");
else {
for (int i=next[n];i;i=next[i]) {
if (cnt[i]) {
for (int j=;j<i;j++)
printf("%c",s[j]);
puts("");
return ;
}
}
puts("Just a legend");
}
return ;
}

还有一种枚举方法是扫描所有可能的中缀末位,取next[i]的最大值,也即求出最大的既是前缀又是中缀的子串,再从next[n]开始走next,第一次走到0<next[i]<=len时,也即找到了子串。

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set> using namespace std; const int N=1e6+;
char s[N];
int next[N];
void getNext(char *word,int n=){
n=(n==)?strlen(word):n;
memset(next,,sizeof(next));
int i,j;
for (i=;i<n;i++){
j=i;
while (j){
j=next[j];
if (word[i]==word[j]){
next[i+]=j+;
break;
}
}
}
}
int main () {
scanf("%s",s);
int n=strlen(s);
getNext(s,n);
int len=;
for (int i=;i<n;i++)
len=max(len,next[i]);
for (int i=next[n];i>;i=next[i]) {
if (i>len) continue;
for (int j=;j<i;j++)
printf("%c",s[j]);
puts("");
return ;
}
puts("Just a legend");
return ;
}

第三种方法是用z算法,也就是算出每个位置与本串的最长公共前缀。再枚举所有后缀,check当前后缀是否也是前缀,如果是的话,则看之前是否有z[i]也就是与本串的LCP大于当前后缀长度,如果有,则当前后缀也一定可以作为中缀出现,当前后缀是最长的符合题意的子串。

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set> using namespace std; const int N=1e6+;
char s[N];
int z[N];
void Z_match(char *s,int n=) {
n=(n==)?strlen(s):n;
z[]=n;
int l=,r=;
for (int i=;i<n;i++) {
if (i>r) {
l=i,r=i;
while (r<n&&s[r-i]==s[r]) r++;
z[i]=r-l;
r--;
}
else {
int k=i-l;
if (z[k]<r-i+)
z[i]=z[k];
else {
l=i;
while (r<n&&s[r-i]==s[r]) r++;
z[i]=r-l;
r--;
}
}
}
}
int main () {
scanf("%s",s);
int n=strlen(s);
Z_match(s,n);
int ret=,maxZ=;
for (int i=;i<n;i++) {
if (z[i]==n-i) {
if (maxZ>=n-i) {
ret=n-i;
break;
}
}
maxZ=max(maxZ,z[i]);
}
if (ret==)
puts("Just a legend");
else {
for (int i=;i<ret;i++)
printf("%c",s[i]);
puts("");
}
return ;
}

CF #93 div1 B. Password KMP/Z的更多相关文章

  1. CF#462 div1 D:A Creative Cutout

    CF#462 div1 D:A Creative Cutout 题目大意: 原网址戳我! 题目大意: 在网格上任选一个点作为圆中心,然后以其为圆心画\(m\)个圆. 其中第\(k\)个圆的半径为\(\ ...

  2. luogu P5410 模板 扩展 KMP Z函数 模板

    LINK:P5410 模板 扩展 KMP Z 函数 画了10min学习了一下. 不算很难 思想就是利用前面的最长匹配来更新后面的东西. 复杂度是线性的 如果不要求线性可能直接上SA更舒服一点? 不管了 ...

  3. CF #344 D. Messenger KMP/Z

    题目链接:http://codeforces.com/problemset/problem/631/D 给定两个压缩形式的字符串,如a3b5a4k7这样的形式 问A在B中出现次数. 分类讨论,如果A是 ...

  4. CF#345 (Div1)

    论蒟蒻如何被cf虐 以下是身败名裂后的题解菌=========== Div1 A.Watchmen 有n个点,每个点有一个坐标.求曼哈顿距离=欧几里得距离的点对数量. 只需要统计x或y一样的点对数量. ...

  5. Codeforces(Round #93) 126 B. Password

    B. Password time limit per test  2 seconds memory limit per test  256 megabytes   Asterix, Obelix an ...

  6. KMP&Z函数详解

    KMP 一些简单的定义: 真前缀:不是整个字符串的前缀 真后缀:不是整个字符串的后缀 当然不可能这么简单的,来个重要的定义 前缀函数: 给定一个长度为\(n\)的字符串\(s\),其 \(前缀函数\) ...

  7. Codeforces126B - Password(KMP)

    题目大意 给定一个字符串S,要求你找到一个最长的子串,它既是S的前缀,也是S的后缀,并且在S的内部也出现过(非端点) 题解 KMP的失配函数f[i]的非零值就是前i个字符的一个最长前缀且也是后缀的字符 ...

  8. CF 508D Tanya and Password(无向图+输出欧拉路)

    ( ̄▽ ̄)" //不知道为什么,用scanf输入char数组的话,字符获取失效 //于是改用cin>>string,就可以了 //这题字符的处理比较麻烦,输入之后转成数字,用到函 ...

  9. CF #356 div1 A. Bear and Prime 100

    题目链接:http://codeforces.com/contest/679/problem/A CF有史以来第一次出现交互式的题目,大致意思为选择2到100中某一个数字作为隐藏数,你可以询问最多20 ...

随机推荐

  1. <context:property-placeholder/>元素

    <context:property-placeholder/>元素 PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口,它 ...

  2. 深入理解java String 及intern

    一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会 ...

  3. 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)

    目录 这是<前端总结·基础篇·JS>系列的第二篇,主要总结一下JS数组的使用.技巧以及常用方法. 一.数组使用 1.1 定义数组 1.2 使用数组 1.3 类型检测 二.常用技巧 2.1 ...

  4. Octave Tutorial(《Machine Learning》)之第二课《数据移动》

    第二课 Moving Data 数据移动 常用内置函数 (1)加载文件 load 文件名.dat(或load('文件名.dat')) 接着输入文件名便可查看文件里的数据 (2)显示当前工作空间的所有变 ...

  5. 菜鸟Scrum敏捷实践系列(一)用户故事概念

    菜鸟Scrum敏捷实践系列索引 菜鸟Scrum敏捷实践系列(一)用户故事概念 菜鸟Scrum敏捷实践系列(二)用户故事验收 菜鸟Scrum敏捷实践系列(三)用户故事的组织---功能架构的规划 敏捷开发 ...

  6. jQuery kxbdMarquee 无缝滚动

    转:http://code.ciaoca.com/jquery/kxbdmarquee/ <marquee> 曾是 IE 下独有的一个走马灯效果的标签,其他浏览器并不兼容,于是出现了使用 ...

  7. SQL动态语句 拼接SQL 并输入输出值

    --动态语句语法 /****************************************************************************************** ...

  8. iOS 将对象的属性和属性值拆分成key、value,通过字符串key来获取该属性的值

    这篇博客光看标题或许就会产生疑问,某个对象,只要它存在某个属性,且值不是空的,不就能直接用点方法获取吗,为什么要拆分成key和value多此一举呢?下面,我用一个例子告诉大家,既然这方法是存在的,那就 ...

  9. taobao-pamirs-proxycache开源缓存代理框架实现原理剖析

    写在前面 taobao-pamirs-proxycache 是一款开源缓存代理框架, 它将 缓存代码 与 业务代码 解耦.让开发专注coding业务, 缓存通过xml配置即可实现.本文先从此工具如何使 ...

  10. WebService基础学习(二)—三要素

    一.Java中WebService规范      JAVA 中共有三种WebService 规范,分别是JAX-WS.JAX-RS.JAXM&SAAJ(废弃).   1.JAX-WS规范    ...