题目链接:https://cn.vjudge.net/contest/276379#problem/J

感觉讲的很好的一篇博客:https://subetter.com/articles/extended-kmp-algorithm.html

题目大意:这是一个编译密码的题目,首先给你26个字母分别重新编码后的对应的字母,然后再给你一个字符串,字符串的前一部分是编译过后的,后一部分是编译之前的,但是后一部分可能会有损失,问你用尽量少的字符,将整个字符串补起来,也就是前面是暗文,后面是明文。

具体思路:扩展kmp的裸题, 我们可以另外开一个字符,这个字符存储的是编译过后的,我们现在把初始密码串比喻成s1,编译过后的密码串比喻成s2,这个样的话,我们直接找出s2中的后缀中,满足是s1的前缀的最长的找出来,这个就是残缺的暗文,前面的就是明文了。

对于扩展kmp的理解:首先说一下我理解的扩展kmp的作用,我们假设当前有一个字符串t,长度是len。t[i]代表的是以字符串的第i位开始,以t[len-1]为截止位置的t的子串,然后nex[i]的作用就是求t[i]和t的最大前缀和的匹配数。

其实extend的作用和nex的具体实现内容是一样的,因为在求nex的时候,我们当前是以t为模板串,t[i]是子串。在求extend的时候,我们是以t为模板串,s是对比串的。

AC代码:

  1. #include<iostream>
  2. #include<stack>
  3. #include<iomanip>
  4. #include<stdio.h>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<string>
  8. #include<map>
  9. #include<cstring>
  10. #include<vector>
  11. using namespace std;
  12. # define ll long long
  13. const int maxn = 1e6+;
  14. char str[maxn],com[maxn];
  15. char tmp[maxn];
  16. int nex[maxn],extend[maxn];
  17. map<char,char>vis;
  18. void getnex(int len)
  19. {
  20. int a=,p=;
  21. nex[]=len;//第0位是自己
  22. for(int i=; i<len; i++)
  23. {
  24. if(i>=p||i+nex[i-a]>=p)
  25. {
  26. if(i>=p)
  27. p=i;
  28. while(p<len&&tmp[p]==tmp[p-i])
  29. p++;
  30. nex[i]=p-i;
  31. a=i;
  32. }
  33. else
  34. nex[i]=nex[i-a];
  35. }
  36. }
  37. void exkmp(int len1,int len2)
  38. {
  39. getnex(len2);
  40. int a=,p=;
  41. for(int i=; i<len1; i++)
  42. {
  43. if(i>=p||i+nex[i-a]>=p)
  44. {
  45. if(i>=p)
  46. p=i;
  47. while(p<len1&&p-i<len2&&str[p]==tmp[p-i])
  48. p++;
  49. extend[i]=p-i;
  50. a=i;
  51. }
  52. else
  53. extend[i]=nex[i-a];
  54. }
  55. }
  56. int main()
  57. {
  58. int T;
  59. scanf("%d",&T);
  60. while(T--)
  61. {
  62. scanf("%s",com);
  63. scanf("%s",str);
  64. for(int i=; i<; i++)
  65. {
  66. vis[com[i]]='a'+i;
  67. }
  68. int len=strlen(str);
  69. for(int i=; i<len; i++)
  70. {
  71. tmp[i]=vis[str[i]];
  72. }
  73. exkmp(len,len);
  74. int i;
  75. for( i=;i<len;i++){
  76. if(i+extend[i]>=len&&i>=extend[i])break;//求满足情况的前缀
  77. }
  78. for(int j=;j<i;j++){
  79. printf("%c",str[j]);
  80. }
  81. for(int j=;j<i;j++){
  82. printf("%c",vis[str[j]]);
  83. }
  84. printf("\n");
  85. }
  86. return ;
  87. }

J - Clairewd’s message HDU - 4300(扩展kmp)的更多相关文章

  1. (KMP 扩展)Clairewd’s message -- hdu -- 4300

    http://acm.hdu.edu.cn/showproblem.php?pid=4300 Clairewd’s message Time Limit: 2000/1000 MS (Java/Oth ...

  2. Clairewd’s message - HDU 4300(next[]运用)

    题目大意:给两个串第一个串是翻译表(密文可以通过翻译表翻译成明文),第二个串是由密文+明文组成,前面是密文(完整的),后面是明文(未必完整),问能不能把第二个串补全,输出最短的一种可能.   分析:题 ...

  3. hdu 4333 扩展kmp+kmp重复字串去重

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 关于kmp next数组求最短重复字串问题请看:http://www.cnblogs.com/z ...

  4. HDU 3336 扩展kmp

    题目大意: 找到字符串中所有和前缀字符串相同的子串的个数 对于这种前缀的问题,通常通过扩展kmp来解决 其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模 ...

  5. hdu 4333(扩展kmp)

    题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个.比如341-->134-->413-->3 ...

  6. HDU 6153 扩展kmp

    A Secret Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)Total ...

  7. HDU 3613 扩展KMP

    暴力枚举大水题,判断回文,扩展KMP #include <cstdio> #include <cstring> #include <algorithm> using ...

  8. hdu 4300 拓展kmp

    题目大意: 输入样例个数,每个样例有两行,第一行是26个字母,分别代表a~z加密后的密文:第二行代表一串密文+明文,密文一定是完整的,但明文可能不完整,让你输出最短的(密文+明文): 基本思路: 拓展 ...

  9. HDU 2594 扩展kmp模板题

    题目大意: 给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀 #include <iostream> #include <cstdio> #include ...

随机推荐

  1. python web调用docker-py

    在 /etc/init.d/docker的start()函数末尾加入:chmod 777 /var/run/docker.sock 否则web程序会没有权限去操作  

  2. response和request的setCharacterEncoding区别

    一.request.setCharacterEncoding():是设置从request中取得的值或从数据库中取出的值. 指定后可以通过getParameter()则直接获得正确的字符串,如果不指定, ...

  3. Java容器深入浅出之HashSet、TreeSet和EnumSet

    Java集合中的Set接口,定义的是一类无顺序的.不可重复的对象集合.如果尝试添加相同的元素,add()方法会返回false,同时添加失败.Set接口包括3个主要的实现类:HashSet.TreeSe ...

  4. ctex2.9.2输出中文

    安装了ctex2.9.2,打开WinEdt7.0 准备编译论文, 但是中文的地方都是空白,不显示, 到网上找了N个方法,就是引入CJK包,然后加入一下CJK命令来控制中文显示, 结果搞得乱七八糟,还是 ...

  5. BZOJ5321 JXOI2017加法(二分答案+贪心+堆+树状数组)

    二分答案后得到每个位置需要被加的次数.考虑贪心.从左到右考虑每个位置,将以该位置为左端点的区间按右端点从大到小加进堆.看该位置还需要被加多少次,如果不需要加了就不管,否则取堆顶区间将其选择,BIT实现 ...

  6. c语言宏定义#define

    1. 利用define来定义 数值宏常量 #define 宏定义是个演技非常高超的替身演员,但也会经常耍大牌的,所以我们用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码就就都认 ...

  7. Oracle 修改dmp的表空间

    1.百度下载  UltraEdit 并安装 2.打开程序,文件-->打开-->找到dmp  文件太大会提示,选择第一个默认,确定 3.按CTRL+H 转成十六进制编辑 4.例如:dmp里面 ...

  8. 【刷题】洛谷 P3834 【模板】可持久化线段树 1(主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

  9. Linux及安全实践二——模块

    Linux及安全实践二--模块 一.模块的编译.生成.测试.删除 1.编写模块代码 编写:gedit 3.c 2.编写Makefile obj-m :这个变量是指定你要声称哪些模块模块的格式为 obj ...

  10. centos install python3 pip3

    yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-dev ...