POJ 2541 Binary Witch(逆序KMP,好题)
逆序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,好题)的更多相关文章
- poj 2541 Binary Witch
Binary Witch http://poj.org/problem?id=2541 Time Limit: 1000MS Memory Limit: 65536K Descript ...
- POJ 1840 Brainman(逆序对数)
题目链接:http://poj.org/problem?id=1804 题意:给定一个序列a[],每次只允许交换相邻两个数,最少要交换多少次才能把它变成非递降序列. 思路:题目就是要求逆序对数,我们知 ...
- POJ 2828 线段树 逆序插入
思路: 1.线段树 逆着插入就OK了 2.块状链表 (可是我并不会写) //By SiriusRen #include <cstdio> #include <cstring> ...
- (中等) POJ 2828 Buy Tickets , 逆序+线段树。
Description: Railway tickets were difficult to buy around the Lunar New Year in China, so we must ge ...
- 【poj 1961】Period(字符串--KMP 模版题)
题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d % ...
- 将单链表的每K个节点之间逆序
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“将单链表的每K个节点之间逆序”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明, ...
- (字符串的处理4.7.16)POJ 1159 Palindrome(让一个字符串变成回文串需要插入多少个字符...先逆序,在减去公共子序列的最大长度即可)
/* * POJ_1159.cpp * * Created on: 2013年10月29日 * Author: Administrator */ #include <iostream> # ...
- poj 2828 Buy Tickets【线段树单点更新】【逆序输入】
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 16273 Accepted: 8098 Desc ...
- POJ 2299 Ultra-QuickSort (求序列的逆序对数)
题意:废话了一大堆就是要你去求一个序列冒泡排序所需的交换的次数. 思路:实际上是要你去求一个序列的逆序队数 看案例: 9 1 0 5 4 9后面比它小的的数有4个 1后面有1个 0后面没有 5后面1个 ...
随机推荐
- Linux 虚拟机和物理机配互信出现无法连接
配置文件位置:[root@hank-yoon data]# vi /etc/ssh/sshd_configPermitRootLogin yes 在物理机中,装完系统,默认情况下PermitRootL ...
- 我爱我家:我为什么选择AppCan?
10年前,说起手机,大家联想到的词大概是:电话.短信.QQ.拍照,以及贪吃蛇等有限的几个小游戏.而如今,手机毫无疑问已经成为人们生活中不可或缺的部分.这是一个神奇的东西:通讯工具,外卖神器,游戏机,移 ...
- hdu 1042 N!
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1042 N! Description Given an integer N(0 ≤ N ≤ 10000) ...
- iOS学习之界面通信
一.属性传值 在SecondViewController.h里 #import <UIKit/UIKit.h> @interface SecondViewController : UIVi ...
- mac os x 系统安装 genymotion android 模拟器
如果你有 apk 文件 想 运行一下看看 ,但是又没有 android 设备 ,那么 genymotion 将会是一个 很好的解决方案. 1.安装 下载链接: https://cloud.geny ...
- Swift给每个开发者赢取500万的机会!不看一生后悔。
[导语] Swift的横空出世,很多有想法的人已经发现其中的蕴含的巨大商机,而很多新手却只是云里雾里,只知道大家最近讨论Swift很欢乐.内行看门道,外行看热闹,说的就是这个理.如果你能把swift用 ...
- PB中掉用Run以后,等Run的程序关闭以后才会执行后边的语句
OleObject wsh integer li_rc CONSTANT integer MAXIMIZED = CONSTANT integer MINIMIZED = CONSTANT integ ...
- [网络配置相关]——netstat命令
netstat:显示网络状态信息 -a 显示所有连接状态的网络的所有选项-l 仅显示LISTEN状态的连接-n 直接显示IP地址,而不通过域名服务器-p 把进程名和进程PID也显示出 ...
- C#如何设置Listview的行高-高度
Winform窗口中,控件listview是无法设置行高的. 以加入一个imagelist(图片列表控件)实现行高的设置. ImageList imageList = new ImageList(); ...
- ScrollView图片分页显示-简单
用到的控件: 1>UIScrollView:宽度和图片的宽度一样,因为分页的代码就一句 // 设置分页,这个分页的原理实际上是按照ScrollView的宽进行分页的,这里的图片的宽由于和Scro ...