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;
}

 

posted @ 2013-01-03 15:43  紫忆  阅读(1021)  评论(0编辑  收藏  举报