逆序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个字母和原字符串从第二个字符开始进行匹配一次就够了!

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <string.h> using namespace std;
const int maxn=+;
char s[maxn],str[maxn];
int next[maxn];
char ans[]; //答案
int n,l;
int start=; //标记字符串的起始位置
int k; void getNext(char*str) {
next[]=;
int k=;
int lm=strlen(str);
for(int i=; i<lm; i++) {
while(k&&str[k]!=str[i])
k=next[k];
if(str[i]==str[k])
k++;
next[i+]=k;
}
}
//逆序KMP,转化为求最长公共前缀
int kmp(char*P,int len) {
int k=,c=,idx;
int lm=strlen(P);
for(int i=start+; i<start+len; i++) {
while(k&&P[k]!=str[i])
k=next[k];
if(P[k]==str[i])
k++;
if(k>c){
c=k;
idx=i;
}
if(k==lm)
return i-k;
}
if(c)
return idx-c;
else
return -;
}
int main()
{
char tmp[];
scanf("%d%d",&n,&l);
scanf("%s",&s);
int len=strlen(s);
for(int i=;s[i];i++){
str[start+i]=s[len--i];
}
str[start+len]='\0';
int cnt=l,k;
while(cnt--){
//截取开始的13个字符
strncpy(tmp,str+start,);
if(len<)
tmp[len]='\0';
else
tmp[]='\0';
getNext(tmp);
k=kmp(tmp,len);
start--;
len++;
if(k==-)
str[start]=''; //不存在匹配的情况
else
str[start]=str[k];
}
for(int i=;i<l;i++)
ans[i]=str[start+l--i];
ans[l]='\0';
printf("%s\n",ans);
return ;
}

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. 安装SRILM

    参考博文:Ubuntu 64位系统下SRILM的配置详解 来源52nlp www.52nlp.cn 首先下载SRILM 解压缩到home即可 然后需要修改MakeFile文件: # SRILM = / ...

  2. iphone/ipad关于size, frame and bounds总结和UIScroll view学习笔记

    1. iphone/ipad大小 Device Screen dimensions(in points) iphone and ipod 320 X 480 ipad 768 X 1024 2. UI ...

  3. R语言将数据框转成xts

    R语言初学者,不怎么会,今天碰到的问题,查了好久才找到,原来如此简单 尼玛,下次再忘记抽自己3巴掌

  4. eclipse集成maven

    1.工具下载: Eclipse4.2 jee版本(这里使用最新的Eclipse版本,3.7以上版本按照以下步骤都可以) 下载地址:http://www.eclipse.org/downloads/do ...

  5. hdu 1228 A + B

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1228 A + B Description 读入两个小于100的正整数A和B,计算A+B.需要注意的是: ...

  6. Unity使用Kinect初级教程

    准备 首先,你需要准备的东西 Windows 8以上系统的电脑,当然,配置不要太渣⊙︿⊙ Kinect for Windows开发套件 安装好Kinect for Windows SDK,这个应该属于 ...

  7. 在 mongodb 终端环境下写多行 javascript 代码、函数

    工作中碰到一个问题,需要把某个 collection 中的某些符合条件的数据取出来,逐行处理其中某些字段.mongodb 终端下支持直接写 js 代码.函数,也可以运行 js 文件.1 首先需要设置 ...

  8. asp.net 间传值的方法

    1.页面间使用post请求时,可以使用Request.Form["xxx"] 2.QueryString 3.Context上下文传值,使用在Server.Transfer中,这个 ...

  9. M1事后分析报告(Postmortem Report)

    M1事后分析报告(Postmortem Report) 设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们项目组所开发的软件为一个基于Andro ...

  10. canvas实现跟随鼠标旋转的箭头

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta ht ...