逆序KMP,真的是强大!

参考链接,下面有题意解释:
http://blog.sina.com.cn/s/blog_6ec5c2d00100tphp.html
http://blog.csdn.net/sdjzping/article/details/8857749
http://tech.ddvip.com/2013-09/1380477442203505.html

直接暴力是枚举字符串的后面13个的字母,然后再用KMP匹配,这样的话,就绪要枚举多次,分别是后面的13,12,11....1个字母。
但是通过观察可以发现,其实要求的是最长公共后缀! 那么可以把原来的字符串逆序转换一下,就变成了求最长公共前缀!
这样只需要求一次,用字符串的前面13个字母和原字符串从第二个字符开始进行匹配一次就够了!

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <string>
  5. #include <string.h>
  6.  
  7. using namespace std;
  8. const int maxn=+;
  9. char s[maxn],str[maxn];
  10. int next[maxn];
  11. char ans[]; //答案
  12. int n,l;
  13. int start=; //标记字符串的起始位置
  14. int k;
  15.  
  16. void getNext(char*str) {
  17. next[]=;
  18. int k=;
  19. int lm=strlen(str);
  20. for(int i=; i<lm; i++) {
  21. while(k&&str[k]!=str[i])
  22. k=next[k];
  23. if(str[i]==str[k])
  24. k++;
  25. next[i+]=k;
  26. }
  27. }
  28. //逆序KMP,转化为求最长公共前缀
  29. int kmp(char*P,int len) {
  30. int k=,c=,idx;
  31. int lm=strlen(P);
  32. for(int i=start+; i<start+len; i++) {
  33. while(k&&P[k]!=str[i])
  34. k=next[k];
  35. if(P[k]==str[i])
  36. k++;
  37. if(k>c){
  38. c=k;
  39. idx=i;
  40. }
  41. if(k==lm)
  42. return i-k;
  43. }
  44. if(c)
  45. return idx-c;
  46. else
  47. return -;
  48. }
  49. int main()
  50. {
  51. char tmp[];
  52. scanf("%d%d",&n,&l);
  53. scanf("%s",&s);
  54. int len=strlen(s);
  55. for(int i=;s[i];i++){
  56. str[start+i]=s[len--i];
  57. }
  58. str[start+len]='\0';
  59. int cnt=l,k;
  60. while(cnt--){
  61. //截取开始的13个字符
  62. strncpy(tmp,str+start,);
  63. if(len<)
  64. tmp[len]='\0';
  65. else
  66. tmp[]='\0';
  67. getNext(tmp);
  68. k=kmp(tmp,len);
  69. start--;
  70. len++;
  71. if(k==-)
  72. str[start]=''; //不存在匹配的情况
  73. else
  74. str[start]=str[k];
  75. }
  76. for(int i=;i<l;i++)
  77. ans[i]=str[start+l--i];
  78. ans[l]='\0';
  79. printf("%s\n",ans);
  80. return ;
  81. }

POJ 2541 Binary Witch(逆序KMP,好题)的更多相关文章

  1. poj 2541 Binary Witch

    Binary Witch http://poj.org/problem?id=2541 Time Limit: 1000MS   Memory Limit: 65536K       Descript ...

  2. POJ 1840 Brainman(逆序对数)

    题目链接:http://poj.org/problem?id=1804 题意:给定一个序列a[],每次只允许交换相邻两个数,最少要交换多少次才能把它变成非递降序列. 思路:题目就是要求逆序对数,我们知 ...

  3. POJ 2828 线段树 逆序插入

    思路: 1.线段树 逆着插入就OK了 2.块状链表 (可是我并不会写) //By SiriusRen #include <cstdio> #include <cstring> ...

  4. (中等) POJ 2828 Buy Tickets , 逆序+线段树。

    Description: Railway tickets were difficult to buy around the Lunar New Year in China, so we must ge ...

  5. 【poj 1961】Period(字符串--KMP 模版题)

    题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d % ...

  6. 将单链表的每K个节点之间逆序

    [说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“将单链表的每K个节点之间逆序”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明, ...

  7. (字符串的处理4.7.16)POJ 1159 Palindrome(让一个字符串变成回文串需要插入多少个字符...先逆序,在减去公共子序列的最大长度即可)

    /* * POJ_1159.cpp * * Created on: 2013年10月29日 * Author: Administrator */ #include <iostream> # ...

  8. poj 2828 Buy Tickets【线段树单点更新】【逆序输入】

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 16273   Accepted: 8098 Desc ...

  9. POJ 2299 Ultra-QuickSort (求序列的逆序对数)

    题意:废话了一大堆就是要你去求一个序列冒泡排序所需的交换的次数. 思路:实际上是要你去求一个序列的逆序队数 看案例: 9 1 0 5 4 9后面比它小的的数有4个 1后面有1个 0后面没有 5后面1个 ...

随机推荐

  1. 应用程序域(Application Domain)

    应用程序域为隔离正在运行的应用程序提供了一种灵活而安全的方法. 应用程序域通常由运行时宿主创建和操作. 有时,您可能希望应用程序以编程方式与应用程序域交互,例如想在不停止应用程序运行的情况下卸载某个组 ...

  2. hdu 1277 全文检索

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1277 全文检索 Description 我们大家经常用google检索信息,但是检索信息的程序是很困难 ...

  3. asp.net实现手机号码归属地查询

    protected void Button1_Click(object sender, EventArgs e)        {            if (Regex.IsMatch(TextB ...

  4. LNMP下wordpress无法切换主题,只显示当前主题解决方法

    最近在lnmp下发现wordpress后台无法切换主题,只能显示当前主题,开始还以为是文件没传完,又重置了一遍,还是一样.百度得知,原来军哥的LNMP安装包默认关闭了scandir函数,为了安全考虑. ...

  5. Status Bar in iOS7

    This is a very important change in iOS 7: the status bar is no longer a separate bar. It’s now somet ...

  6. 如何配置DNS服务器(局域网——域名指向某个IP地址)

    单击“开始”,指向“管理工具”,然后单击“DNS”,打开 DNS 管理器.   如有必要,向管理单元添加适用的服务器,然后连接该服务器.在控制台树中,单击适用的 DNS 服务器.   在“操作”菜单上 ...

  7. .net 使用validator做数据校验

    概述 在把用户输入的数据存储到数据库之前一般都要对数据做服务端校验,于是想到了.net自带的数据校验框架validator.本文对validator的使用方法进行介绍,并分析下校验的的原理. 使用va ...

  8. EasyUI 兼容 IE6 方法总结

    1.combobox 如果单选,multiple必须也设置为true.这个ie7如果没设置,会保持多选状态,算是一个bug. 2.combobox 最好用js来渲染,而不是一开始就class=“eas ...

  9. Ubuntu 关闭锁屏界面的 on-screen keyboard

    试了试屏幕键盘,在 系统设置里开启了,又关了,但是在屏幕解锁时总是出现 screen keyboard,老烦人了,不知到在哪里关闭了,系统设置里面都关了,网上搜了解决办法,原来在这里 把 show w ...

  10. My mac cannot run 类相关的操作 , which is lower than 类相关的操作。

     首先你选择的项目是mac项目,    其次,你MAC的系统版本小于你当前项目部署环境的最低支持版本    要么升级你的MAC系统,要么再project—>target设置developerme ...