博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【题解】洛谷P4391 [BOI2009] Radio Transmission(KMP)
阅读量:4579 次
发布时间:2019-06-09

本文共 900 字,大约阅读时间需要 3 分钟。

洛谷P4391:

思路

对于给定的字符串

运用KMP思想

设P[x]为前x个字符前缀和后缀相同的最长长度

则对于题目中的长度len有:

len-p[len]为第一个重复子串的最后一个字符位置

因此len-p[len]即重复子串长度

证明:

因为p[len]为前len个字符中前缀和后缀相同的最长长度

先对于一个重复串来观察

abcd abcd abcd

则对于p[12]=8 就是它后面多出来的重复串

总长把多出来的重复串减去即可得到原始重复串的长度

通过题目已经知道原串是一条自重复串

那么不妨设x为原始重复串的长度 则x+1到len都是他重复的部分

因此我们求出p[len]就是后面重复部分的长度

则len-p[len]就满足原始重复串的长度

模拟样例:

字符串:c a b c a b c a

对应P: 0 0 0 1 2 3 4 5

则len-p[len]的位置为3

因为1~5的cabca与4~8的cabca相同

对于4~8的字符串都是原始字符串的重复部分

所以只要再补上一个b

即可满足重复串cabcabcab

代码

#include
#include
#include
using namespace std;#define maxn 1000010char a[maxn];int p[maxn];int len,j;int main(){ scanf("%d",&len); scanf("%s",a+1); for(int i=2;i<=len;i++)//常规KMP求P数组 { while(j&&a[j+1]!=a[i]) j=p[j]; if(a[j+1]==a[i]) j++; p[i]=j; } printf("%d",len-p[len]);//输出原始重复串长度 }

转载于:https://www.cnblogs.com/BrokenString/p/9781626.html

你可能感兴趣的文章
SpringMvc数据校验@Valid等注解的使用与工具类抽取
查看>>
手势相关函数
查看>>
ActiveReports 报表控件官方中文入门教程 (1)-安装、激活以及产品资源
查看>>
求所有水仙花数
查看>>
有关欧拉通路/回路的一些资料整理
查看>>
PDF虚拟打印机怎么保存文件
查看>>
使用VisualVM监控远程服务器JVM
查看>>
WIN10发布.NET网站报错
查看>>
SVN解决本地版本控制与服务器版本冲突问题
查看>>
Linux/python
查看>>
JavaScript--微博发布效果
查看>>
资源、学习网站网址
查看>>
ubuntu安装docker
查看>>
写些什么
查看>>
Ubuntu第一次使用注意点
查看>>
带有左右点击按钮的图片轮播图
查看>>
CDQ分治入门 + 例题 Arnooks's Defensive Line [Uva live 5871]
查看>>
如何在MyBatis中优雅的使用枚举
查看>>
SCVMM 2012 SP1 安装
查看>>
可做爬虫的jsoup常用方法,附异步请求实现
查看>>