您的位置:首页 > 大数据 > 人工智能

HDU 4300 Clairewd’s message

2016-07-20 18:02 459 查看




题意说明:首先我个人感觉这道题题意不是很好理解的。我当时理解了很久,至少花了一个上午加一个下午才理解了题意。大致就是一个调查局,截获了一段重要信息,但是由于对方有所察觉,所有获取到的信息有缺漏,这重要信息由密文+明文组成,密文是完整的,明文是残缺的(也可能全部为密文),现在要求你补全明文,输出密文+明文。

第一个数字T是测试数据的组数,接下来每两行是给定的两个字符串,第一个字符串是为指定长度26的翻译表,分别表示a-z匹配到什么字符。

第二个字符串是待补全的信息,由密文+明文组成,密文在前面,明文在后面,这里注意了,也有可能全部为密文

解题思路:把给定的翻译表记为str,那么截获了重要信息就为str1,由题意可知密文长度肯定是大于等于明文长度的。所以我们可以把str1的前一半转换成明文(前一段必定为密文) 与后一半进行匹配,如果从后面某个位置能匹配到末尾,则表示那一部分是明文,然后进行补充完整输出即可

下面我就直接上代码了。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
using namespace std;
const int maxn=200030;
char str[maxn],str1[maxn],str2[maxn],zimu[27];
int _next[maxn];
void get_next(int len)
{
int i=-1,j=0;
_next[0]=-1;
while(j<len)
{
if(i==-1||str2[i]==str2[j])
{
++i,++j;
_next[j]=i;
}
else
i=_next[i];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s %s",str,str1);
int len=strlen(str1);
printf("%s",str1);//因为只是明文可能有缺失,所以先把当前的信息输出,后面只需要求出缺失的信息。
for(int i=0;i<26;i++)
{
zimu[str[i]-'a']=i+'a';//zimu表示密文翻译成明文的翻译表,后面需要通过密文反翻译成明文
}
for(int i=0;i<((len+1)>>1);i++)
{
str2[i]=zimu[str1[i]-'a'];//把str1前一半的密文转化为明文赋给str2
}
for(int i=((len+1)>>1);i<len;i++)
{
str2[i]=str1[i];//把str1后一半的内容赋给str2
}
str2[len]='\0';//注意!!!!!!
get_next(len);//next数组  重点!!!!!!
int k=len;
while(_next[k]>(len>>1))//明文长度不可能超过总长度的一半
{
k=_next[k];
}
for(int i=_next[k];i<len-_next[k];i++)//通过反翻译输出缺失的信息
printf("%c",zimu[str1[i]-'a']);
printf("\n");
}
return 0;
}


END!!!!!!!!!!!!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: