HDU 4300Clairewd’s message 扩展kmp || kmp
来源:互联网 发布:淘宝几天可以申请售后 编辑:程序博客网 时间:2024/05/07 09:25
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4300
题意:有一段字符串由密文和明文组成,密文是完好的,明文可能是残缺的。首先给出密文转换表,然后给出密文明文字符串,然后复原出最短的密文明文字符串(补上明文)
思路:可以用扩展kmp求解。首先,明文的起始位置一定在字符串后半段(密文 >= 明文),于是把前半段转换成明文,然后用扩展kmp求每一个位置和字符串的最长公共前缀长度,后半段中满足next[i] + i = len的i,一定是明文的起始位置,因为这代表从i开始以后完全重合与字符串首部的一段字符。注意明文可能完全丢失
扩展kmp
#include <iostream>#include <algorithm>#include <cstdio>#include <queue>#include <map>#include <vector>#include <cstring>#include <cmath>#include <set>using namespace std;const int N = 100010;int nt[N];char s1[100], s2[N], s3[N], tab[100];void getnt(char s[]){ int p = 0, len = strlen(s); nt[0] = len; while(p + 1 < len && s[p] == s[p+1]) p++; nt[1] = p; int k = 1; for(int i = 2; i < len; i++) { if(nt[i-k] + i < nt[k] + k) nt[i] = nt[i-k]; else { int j = nt[k] + k - i; if(j < 0) j = 0; while(i + j < len && s[i+j] == s[j]) j++; nt[i] = j; k = i; } }}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%s%s", s1, s2); int len = strlen(s2); for(int i = 0; i < 26; i++) tab[s1[i]-'a'] = i + 'a'; //密文字符对应的明文字符 for(int i = 0; i < (len + 1) / 2; i++) s3[i] = tab[s2[i]-'a']; //密文转明文 for(int i = (len + 1) / 2; i <= len; i++) s3[i] = s2[i]; getnt(s3); int res = len; //当找不到公共前缀时,意味整个串都是密文,所以预先给res赋值为len for(int i = (len + 1) / 2; i < len; i++) if(nt[i] + i == len) //条件成立说明从i位置开始到末尾是字符串的前缀,认为从i开始是明文 { res = i; break; } printf("%s", s2); for(int i = len - res; i < res; i++) printf("%c", tab[s2[i]-'a']); printf("\n"); } return 0;}
kmp做法。思路也是求后半段中和字符串的最长公共前缀长度
#include <iostream>#include <algorithm>#include <cstdio>#include <queue>#include <map>#include <vector>#include <cstring>#include <cmath>#include <set>using namespace std;const int N = 100100;int nt[N];char s1[100], tab[100], s2[N], s3[N];void getnt(char s[]){ int i = 0, j = -1; nt[0] = -1; while(s[i]) { if(j == -1 || s[i] == s[j]) { i++, j++; if(s[i] != s[j]) nt[i] = j; else nt[i] = nt[j]; } else j = nt[j]; }}int kmp(char s1[], char s2[], int len){ getnt(s2); int i = (len + 1) / 2, j = 0; while(s1[i]) { if(j == -1 || s1[i] == s2[j]) i++, j++; else j = nt[j]; } return j;}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%s%s", s1, s2); int len = strlen(s2); for(int i = 0; i < 26; i++) tab[s1[i]-'a'] = i + 'a'; for(int i = 0; i < (len + 1) / 2; i++) s3[i] = tab[s2[i]-'a']; for(int i = (len + 1) / 2; i <= len; i++) s3[i] = s2[i]; int res = kmp(s2, s3, len); printf("%s", s2); for(int i = res; i < len - res; i++) printf("%c", tab[s2[i]-'a']); printf("\n"); } return 0;}
0 0
- hdu 4300 Clairewd’s message 扩展kmp
- hdu 4300 Clairewd’s message(扩展KMP)
- HDU 4300 Clairewd’s message(扩展KMP)
- hdu 4300 Clairewd’s message (扩展kmp)
- HDU 4300Clairewd’s message 扩展kmp || kmp
- hdu 4300 Clairewd’s message(详解,扩展KMP)
- HDU 4300 Clairewd’s message(扩展KMP)
- HDU 4300 Clairewd’s message(扩展kmp)
- HDU-4300 Clairewd’s message + 4333(扩展KMP)
- hdu 4300 Clairewd’s message(扩展KMP)
- HDU 4300 Clairewd’s message(扩展KMP)
- HDOJ 4300 Clairewd's message(扩展KMP)
- 【扩展KMP】 HDOJ 4300 Clairewd’s message
- hdu - 4300 - Clairewd’s message- kmp
- HDU 4300 Clairewd’s message(拓展KMP)
- KMP hdu-4300 Clairewd’s message
- HDU 4300 Clairewd’s message KMP
- hdu 4300 Clairewd’s message(KMP)
- 客户端早会 每日一享(关于需要动态更换图片的接口处理技巧?)
- 实现单链表的创建、打印、插入、删除、逆置
- HDU 4990 Reading comprehension(找规律)(矩阵快速幂)
- 为JFace(TableViewer,TreeViewer...)创建可直接编辑的DialogCellEditor
- spring的事务管理器有几种
- HDU 4300Clairewd’s message 扩展kmp || kmp
- 绕过web认证学习总结
- JDBC总结
- Cookie and Session
- [HDU2462] The Luckiest number [2008 Asia Hefei Regional Contest Online G]
- 妻子怀胎十月,去遭到了这样的待遇。。。。。。
- 每日一享(工作心态对自己成长的影响?)
- UI网络笔记(四):UI网络之解析XML数据的三种方式
- BackupYourSystem/TAR