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;
}
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。

浙公网安备 33010602011771号