解密
2015-08-19 20:26
225 查看
题意
Mirko要解一段加密文,但他只知道某一个句子是原文的一部分。你的任务是要在密文中找到第一个对应这个句子的地方。文段是通过用某个单词(可能和原文一样的单词)替换原始文段每一个单词来加密的。如果某些单词在原文出现一次以上,就会使用相同的替换单词来替换。没有两个不同的单词使用相同的替换单词。
单词是通过空格隔开的小写字母序列。句子是连续单词的序列。
文段、句子长度不超过10610^6
TimeTime Limits:2000msLimits:2000ms
MemoryMemory Limits:64MLimits:64M
分析
我们发现,如果一段密文是由原文加密而来的,那该段密文中每两个相同单词间的间距要与原文中每两个相同单词间的间距相同。我们可用f[i]f[i]表示原文句子的第ii个单词与它后面距离为f[i]f[i]的单词相同。这样得出一个新的数组(可以看成一个新的字符串),然后对于密文做同样的处理。若一段密文满足条件,则该段密文的新字符串要与原文的新字符串相同。问题到这里就比较显然了,我们可以用哈希求出原文新字符串对应的哈希值,然后动态维护一段长度与原文长度相同的密文字符串的哈希值。即从左往右扫原文,每将我们将当前枚举的那段密文串向右移一位,就减去原来最左边的密文串的f[l−1]f[l - 1]对哈希值的影响,再加上当前新结尾的f[r]f[r]对哈希值的影响。然后再将当前哈希值与目标哈希值比较。
但这样我们又会发现一个问题,就是如果密文串中的一个f[i]+if[i] + i指向的位置超过了当前枚举的密文串的结尾,那么这个f[i]f[i]应暂时为00,当结尾扫到f[i]+if[i] + i时再将它加进去(若此时ii已不在枚举的密文串内略过)。所以我们可以用一个数组记录这个单词前面的与它最近的相同的单词的位置,当新扫到一个位置时用该数组值更新哈希值。
相关文章推荐
- 前端开发必须知道的JS(二) 闭包及应用
- UVA11111套娃匹配题,注意字符串流使用简化代码
- 好久没来了
- Menu,dialog的用法
- linux 命令 - 命令搜索命令 whereis which
- Interpolator的几种属性
- 在写extjs中一个panel里放了3个grid,但就是不显示页面,后台给出数据,前台也有加载数据
- 前端开发必须知道的JS(一) 原型和继承
- Activity的启动, android 任务栈及启动模式 ,Intent的用法
- POJ-1200(哈希)
- 设置 ProgressBar 进度条(条形) 的颜色和用代码动态控制显示的长度
- 黑马程序员----多线程的两种实现方法
- 华为成为 Linux 基金会白金会员
- 2015/8/19/横、竖、满屏/消除标题、标题栏/startActivityForResult(启动带有返回值的intent)/Intent
- 2015 HUAS Summer Trainning #6~J
- PostgreSQL Replication之第一章 理解复制概念(2)
- HDU1465 第六周L题(错排组合数)
- 在Linux DeviceTree添加dtsi文件并在驱动中读取节点信息写入sys文件系统
- PHP实现用户登录和注册的功能
- Java中异常的写法