[DBSDFZOJ 多校联训] Password
2017-08-07 17:00
176 查看
Password
password.in/.out描述
你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s。传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s 的后缀并且还在 s 的中间位置出现过一次。
如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个。
如果不存在这样的串,输出"Just a legend"(去掉引号)。
输入格式
仅一行,字符串 s。输出格式
如题所述样例输入
fixprefixsuffix
样例输出:
fix
数据范围
对于 60%的数据, s 的长度<=100对于 100%的数据, s 的长度<=100000
看到"同时是前缀与后缀的串的长度"可能大家都能想到 $KMP$ 算法w
但是题目对于这个串有一定限制: 必须在中间出现过至少一次. 所以我们计算出这个串的长度之后还要拿着这个串进原串匹配一发, 如果匹配次数达到 $3$ 或以上就说明这个串除了在两端出现过之外还在中间出现了至少一次. 如果没有在中间出现则在刚刚验证失败的子串内接着找同时是这个串前缀与后缀的串的最大长度.
也就是说先求 $KMP$ 中的失配边, 然后在不符合题意的时候一直跳失配边就好了.
跳到最后还是没有匹配到说明无解.
(考试的时候输入数据神特么文件尾没有空行(╯‵□′)╯︵┻━┻逐字符读入直接死循环然后本来能A的题...裱死出数据的家伙)
参考代码:
GitHub
#include <cctype> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> const int MAXN=100010; int len; int fail[MAXN]; char buffer[MAXN]; int Read(char*); void Print(char*,int); void KMP(char*,int*,int); int Match(char*,int,char*,int,int*); int main(){ scanf("%s",buffer); len=strlen(buffer); KMP(buffer,fail,len); for(int k=fail[len];k>0;k=fail[k]){ if(Match(buffer,len,buffer,k,fail)>2){ Print(buffer,k); return 0; } } puts("Just a legend"); return 0; } void KMP(char* buf,int* f,int len){ int j=0,k=-1; f[0]=-1; while(j<len){ if(k==-1||buf[j]==buf[k]){ f[++j]=++k; } else k=f[k]; } } int Match(char* buf,int lb,char* ptn,int lp,int* f){ int j=0,ans=0; for(int i=0;i<lb;i++){ while(j>0&&buf[i]!=ptn[j]) j=f[j]; if(buf[i]==ptn[j]) j++; if(j==lp){ ans++; j=f[j]; } } return ans; } inline void Print(char* buf,int len){ for(int i=0;i<len;i++){ putchar(buf[i]); } putchar('\n'); } inline int Read(char* buf){ int pos=0; do{ buf[pos]=getchar(); }while(isspace(buf[pos])); while(!isspace(buf[pos])&&buf[pos]!=EOF){ buf[++pos]=getchar(); } buf[pos]='\0'; return pos; }
Backup
相关文章推荐
- [DBSDFZOJ 多校联训] 就
- 【DBSDFZOJ 4370】小宁的机器人(模拟)
- 【DBSDFZOJ 4844】区间(分治)
- 【DBSDFZOJ 4845】三元组(树状数组)
- 【DBSDFZOJ 4846】攻略(贪心)
- 【DBSDFZOJ 4847】环线(矩阵快速幂)
- 【DBSDFZOJ 4415】黄金拼图(乱搞)
- 【DBSDFZOJ 4445】棋盘(组合数学-错排公式+高精度)
- 【乱搞】【DBSDFZOJ 4415】黄金拼图
- 【转】【DBSDFZOJ 1163】分治 第K小元素(分治)
- 【DBSDFZOJ 4448】a(乱搞)
- 【模板】进制转换【DBSDFZOJ】
- 【DBSDFZOJ 4460】666(DP)
- 【DBSDFZOJ 4409】a(离散化+树状数组)
- 【DBSDFZOJ 4430】陶陶摘苹果(DP)
- django.db.utils.OperationalError: (1045, "Access denied for user 'root'@'127.0.0.1' (using password:
- 12c dbca CRS-2674: Start of 'ora.orcl.db' on 'rac1' failed ORA-01017: invalid username/password; log
- zoj 2915 hdu 2397 Dice Password Security 动态规划
- [DFS]FJSDFZOJ 1261 整数拆分
- zoj 2915 hdu 2397 Dice Password Security