hdu 4468 spy 极其精彩的一道kmp灵活运用题
出的超级好的一道题。至于好在哪里,请思考题目:
题意抽象出来为给定一个字符串r,找出它的一个最短后缀s,使得这个r可以被 s的某前缀+s的某前缀+......+s的某前缀+s本身构造出来。
具体题目描述如下:
“Be subtle! Be subtle! And use your spies for every kind of business. ”
— Sun Tzu
“A spy with insufficient ability really sucks”
— An anonymous general who lost the war
You, a general, following Sun Tzu’s instruction, make heavy use of spies and agents to gain information secretly in order to win the war (and return home to get married, what a flag you set up). However, the so-called “secret message” brought back by your spy, is in fact encrypted, forcing yourself into making deep study of message encryption employed by your enemy.
Finally you found how your enemy encrypts message. The original message, namely s, consists of lowercase Latin alphabets. Then the following steps would be taken:
* Step 1: Let r = s
* Step 2: Remove r’s suffix (may be empty) whose length is less than length of s and append s to r. More precisely, firstly donate r[1...n], s[1...m], then an integer i is chosen, satisfying i ≤ n, n - i < m, and we make our new r = r[1...i] + s[1...m]. This step might be taken for several times or not be taken at all.
What your spy brought back is the encrypted message r, you should solve for the minimal possible length of s (which is enough for your tactical actions).
输入:
There are several test cases.
For each test case there is a single line containing only one string r (The length of r does not exceed 10 5). You may assume that the input contains no more than 2 × 10 6 characters.
Input is terminated by EOF.
输出:
For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) and Y is the desired answer.
样例:
abc
aab
abcadabcabcad
aaabbbaaaabbbaa
abcababcd 样例答案:
Case 1: 3
Case 2: 2
Case 3: 5
Case 4: 6
Case 5: 4 题解:
这题初看很容易只能想到枚举答案长度i,从r后面截长度为i的后缀然后暴力匹配是否满足条件。复杂度显然太高无法接受。
之后如果运用动态规划的思想,可以对r[1...k]考虑子问题。
但是会发现由于要加一个s本身,考虑完全同质的子问题有点问题。
于是考虑r[1...k]可以表示为s1某前缀+s1某前缀+...+s1某前缀时s1的最短长度
那么对于r[1...k+1],
如果r[k+1]可以成为s1的某前缀的一部分或者自己成为s1的前缀。s1就仍然满足r[1....k+1]的要求,最短长度不变;
如果不可以,那么理论上把s1的末尾添加字符r[k+1]便满足了r[1...k+1]的要求。但是这时得考虑下最后得有一个s本身的问题。
所以添加字符的时候不能只加r[k+1],应该加一段字符。从r[1...k+1]中上一次模板串跟r[1..k+1]的一部分完全匹配的地方开始加,加到r[k+1]。
一直扫描完题意给的整个r。最后再给一直维护的模板串加一段:最后一次完全匹配的地方到r的末尾的字符。
以上是思考过程。 以下是更加严谨的题解叙述:
从头开始扫描r,始终维护一个模板串s和上一次完全匹配位置的标记mark:
在r[i]处有三种操作:
1.若在r[i]处成功进行kmp匹配,则模板串不变
2.如匹配失败,动态添加模板串,添加内容为位置为mark至i的子串
3.如果进行了一次完全匹配,更新mark。
#include<cstdio>
#include<cstring>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int MAXN=;
char s[MAXN];
char ans[MAXN];
int next[MAXN];
int tot;
int main()
{
//freopen("in.txt","r",stdin);
int cnt=;
while(scanf("%s",s)!=EOF)
{
int len=strlen(s);
tot=;
ans[tot++]=s[]; //将维护的模板串初始化
next[]=;
int mark=; //mark标记上一次完全匹配的位置
for(int i=,k=;i<len;++i)
{
while(k>&&s[i]!=ans[k]) //尝试s[i]是否能成为维护的模板串前缀的一部分
{
k=next[k-];
}
if(s[i]==ans[k]) k++;
else if(k==) //尝试失败
{
for(int j=mark+;j<=i;++j) //更新模板串
{
ans[tot++]=s[j];
int tmp=next[tot-]; //模板串的next数组需要跟着动态更新
while(tmp>&&ans[tmp]!=ans[tot-]) tmp=next[tmp-];
if(ans[tmp]==ans[tot-]) tmp++;
next[tot-]=tmp;
}
mark=i;
}
if(k==tot) mark=i,k=next[tot-]; //进行了一次完全匹配,更新mark,并将k跳回
}
for(int j=mark+;j<len;++j) ans[tot++]=s[j];
printf("Case %d: %d\n",++cnt,tot);
}
return ;
}
做出来之后发现这道题考察到了kmp算法的所有操作。但是需要人将其kmp算法的各个操作有机地拆开与重组,来解决这个新的问题。
非常有助于加深对kmp的理解。
hdu 4468 spy 极其精彩的一道kmp灵活运用题的更多相关文章
- HDU 4468 Spy(KMP+贪心)(2012 Asia Chengdu Regional Contest)
Description “Be subtle! Be subtle! And use your spies for every kind of business. ”― Sun Tzu“A spy w ...
- HDU - 4333 :Revolving Digits (扩展KMP经典题,问旋转后有多少个不同的数字小于它本身,等于它本身,大于它本身。)
One day Silence is interested in revolving the digits of a positive integer. In the revolving operat ...
- hdu 1711 Number Sequence(KMP模板题)
我的第一道KMP. 把两个数列分别当成KMP算法中的模式串和目标串,这道题就变成了一个KMP算法模板题. #include<stdio.h> #include<string.h> ...
- HDU 1711 Number Sequence(KMP裸题,板子题,有坑点)
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 1711 - Number Sequence - [KMP模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- HDU 1711 Number Sequence (字符串匹配,KMP算法)
HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...
- 13-Oulipo(kmp裸题)
http://acm.hdu.edu.cn/showproblem.php?pid=1686 Oulipo Time Limit: 3000/1000 MS (Java/Others) Memo ...
- zstu.4194: 字符串匹配(kmp入门题&& 心得)
4194: 字符串匹配 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 206 Solved: 78 Description 给你两个字符串A,B,请 ...
- hdu 5288||2015多校联合第一场1001题
pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...
随机推荐
- SVG视野
前面的话 SVG中坐标系统非常关键,但在介绍坐标系统之前,首先要了解视野.本文将详细介绍SVG视野 视野 下面来区分视窗.世界和视野 [视窗] SVG的属性width.height来控制视窗的大小,也 ...
- Android studio 安装的安装一些问题
在国内如何更新android sdk? 由于众所周知的某些原因,我们无法直接连接android sdk的更新服务更新sdk,所以可以通过国内的ftp站点把常用的sdk组件如android platfo ...
- httpd常用配置
author:JevonWei 版权声明:原创作品 检查配置文件时,如下提示,则因为没有server的服务名称导致,故设置网站的服务server名称,若没有设置web服务名,主默认解析系统主机名(添加 ...
- 有var和没有var的本质区别
我们创建一个变量: var a = 100: 同时,大家也知道,就是不写var关键字也可以创建.在很多教程和说法中,将没有var 的这个名称称之为“全局变量”.如果我在全局直接写一个var abc = ...
- Java并发之线程
在前面我们介绍的一些内容中,我们的程序都是一条执行流,一步一步的执行.但其实这种程序对我们计算机的资源的使用上是低效的.例如:我们有一个用于计算的程序,主程序计算数据,在计算的过程中每得到一个结果就需 ...
- [自制操作系统] JOS文件系统详解&支持工作路径&MSH
本文分为两部分: 第一部分将详细分析JOS的文件系统及文件描述符的实现方法. 第二部分将实现工作路径,提供新的系统调用,完善用户空间工具. 本文中支持的新特性: 支持进程工作目录 提供getcwd与c ...
- 【★】SPF(Dijkstra)算法完美教程
- ★10 个实用技巧,让Finder带你飞~
10 个实用技巧,让 Finder 带你飞 Finder 是 Mac 电脑的系统程序,有的功能类似 Windows 的资源管理器.它是我们打开 Mac 首先见到的「笑脸」,有了它,我们可以组织和使用 ...
- .opt,frm,.MYD,.MYI文件如何转为.sql文件?
假如你是网站测试人员,数据库管理员从服务器上导出数据库,如下图: 你会发现这不是.sql文件,需要将其转化. 其实很简单,只要你本地比如D盘有安装“phpstudy”和“SQLyog”就可以,你可以直 ...
- string和double之间的相互转换(C++)
很多人都写过这个标题的文章,但本文要解决的是确保负数的string和double也可以进行转换. 代码如下: string转double double stringToDouble(string nu ...