hdu4300
http://acm.hdu.edu.cn/showproblem.php?pid=4300
题意:题目大意是有一份文件,前面是密文,后面是原文,但那个人接到这个文件后不知道中间从哪里开始是原文,所以你要帮忙还原一下,如果后面原文比密文少,你就将它补全。
思路:将它给出的明文加密文全部转换一次,将转换了的做模式串,与原串进行kmp,记录返回的j值,j值代表的就是前缀和后缀的最长相等长度。当然,在比较时要注意,密文长度肯定要>=明文长度,所以在匹配的时候,要保证前面比后面长,以免出现错误。
#include<iostream> #include<string.h> using namespace std; char t[100006],s[100006],str1[26]; int next[100006],str[1000]; void getnext() { int i=0,j=-1; next[0]=-1; int len=strlen(s); while(i<len) { if(j==-1||s[i]==s[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int kmp() { int i,j=0; int lent=strlen(t); int lens=strlen(s); if(lent%2==1) i=lent/2+1; else i=lent/2; while(i<lent&&j<lens) { if(j==-1||t[i]==s[j]) { i++; j++; } else j=next[j]; //printf("%d\n",j); } return j; } int main() { int text; scanf("%d",&text); while(text--) { char ch; int i; scanf("%s",str1); for(i=0;i<26;i++) { ch=str1[i]; str[ch]=i; } scanf("%s",t); int lent=strlen(t); for(i=0;i<lent;i++) { int temp=str[t[i]]; s[i]=temp+'a'; } // printf("%s\n%s\n",t,s); // printf("%s\n%s\n",t,s); getnext(); int j=kmp(); if(j*2==lent) { printf("%s\n",t); } else { int tmp1=lent-j; printf("%s",t); for(i=j;i<tmp1;i++) printf("%c",s[i]); printf("\n"); } } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。