CF #93 div1 B. Password KMP/Z
题目链接: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的更多相关文章
- CF#462 div1 D:A Creative Cutout
CF#462 div1 D:A Creative Cutout 题目大意: 原网址戳我! 题目大意: 在网格上任选一个点作为圆中心,然后以其为圆心画\(m\)个圆. 其中第\(k\)个圆的半径为\(\ ...
- luogu P5410 模板 扩展 KMP Z函数 模板
LINK:P5410 模板 扩展 KMP Z 函数 画了10min学习了一下. 不算很难 思想就是利用前面的最长匹配来更新后面的东西. 复杂度是线性的 如果不要求线性可能直接上SA更舒服一点? 不管了 ...
- CF #344 D. Messenger KMP/Z
题目链接:http://codeforces.com/problemset/problem/631/D 给定两个压缩形式的字符串,如a3b5a4k7这样的形式 问A在B中出现次数. 分类讨论,如果A是 ...
- CF#345 (Div1)
论蒟蒻如何被cf虐 以下是身败名裂后的题解菌=========== Div1 A.Watchmen 有n个点,每个点有一个坐标.求曼哈顿距离=欧几里得距离的点对数量. 只需要统计x或y一样的点对数量. ...
- Codeforces(Round #93) 126 B. Password
B. Password time limit per test 2 seconds memory limit per test 256 megabytes Asterix, Obelix an ...
- KMP&Z函数详解
KMP 一些简单的定义: 真前缀:不是整个字符串的前缀 真后缀:不是整个字符串的后缀 当然不可能这么简单的,来个重要的定义 前缀函数: 给定一个长度为\(n\)的字符串\(s\),其 \(前缀函数\) ...
- Codeforces126B - Password(KMP)
题目大意 给定一个字符串S,要求你找到一个最长的子串,它既是S的前缀,也是S的后缀,并且在S的内部也出现过(非端点) 题解 KMP的失配函数f[i]的非零值就是前i个字符的一个最长前缀且也是后缀的字符 ...
- CF 508D Tanya and Password(无向图+输出欧拉路)
( ̄▽ ̄)" //不知道为什么,用scanf输入char数组的话,字符获取失效 //于是改用cin>>string,就可以了 //这题字符的处理比较麻烦,输入之后转成数字,用到函 ...
- CF #356 div1 A. Bear and Prime 100
题目链接:http://codeforces.com/contest/679/problem/A CF有史以来第一次出现交互式的题目,大致意思为选择2到100中某一个数字作为隐藏数,你可以询问最多20 ...
随机推荐
- oracle lag与lead分析函数简介
lag与lead函数是跟偏移量相关的两个分析函数,通过这两个函数我们可以取到当前行列的偏移N行列的值 lag可以看着是正的向上的偏移 lead可以认为负的向下的偏移 具体我们来看几个例子: 我们先看下 ...
- java基础:数组的拼接
- 学习HTML5一周的收获1
HTML5的基本结构 学习了title标签(显示网站名称),link标签(链接文件,可做网页美化) 快捷键:Ctrl+/ 注释 学习[meta标签] 1.charset属性:单独使用,设置文档字符集编 ...
- 关于使用lazytag的线段树两种查询方式的比较研究
说到线段树,想来大家并不陌生——最基本的思路就是将其规划成块,然后只要每次修改时维护一下即可. 但是尤其是涉及到区间修改时,lazytag的使用往往能够对于程序的质量起到决定性作用(Ex:一般JSOI ...
- FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 通过对比WebForms和MVC中表格数据库分页代码的不同,可以对 MVC 中的数据流转有更加深入的了解. WebForms 中 ...
- pom.xml配置文件配置jar(不用记,快速配置)
1:网址:http://mvnrepository.com/ 2:在搜索栏搜索要用的框架;例如spring *以下为示例
- JDBC连接数据以及操作数据
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- ECMA script 6的新特性
简单介绍下ES6的新特性: (1)箭头操作符 :简化了函数的书写 (2)类的支持:引入了class关键字,对象的创建,继承更加直观,父类方法的调用,实例化,构造函数等概念更加形象化. (3)增强的对象 ...
- Previous operation has not finished; run 'cleanup' if it was interrupted
在使用myeclipse的时候,点击保存的时候,控制台窗口总是弹出这个svn :Previous operation has not finished; run 'cleanup' if it was ...
- Webstorm编译TypeScript报错
Accessors are only available when targeting ECMAscript 5 and higher. 解决办法: File Watchers 在tsc.cmd命令上 ...