题面
题目描述
Alice和Bob正在悄悄地给对方发信息,信息都是由英文小写字母组成的,他们约定,所有的字母都得经过一个字母表进行变换,以防泄漏。另一方面John却在监听。
John发现,Alice和Bob通信的时候,总是先发送加密后的密文,然后紧接着发送原文。
但是Alice和Bob似乎也意识到了似乎有人监听,有时候会随意中断了他们的通信。不过每次都是在发送完密文之后才停止传送的。也就是说,John截获到的信息是密文的全文以及前一部分原文。原文可能一个字符都没有,也可能原文的全文都被截获。
现在John比较头疼,他虽然已经得到了他们两个人通信的加密字母表,但是分不清楚什么地方是密文和明文的分界线。你能帮他还原回完整的传输内容吗?
如果有多种可能时,John认为那个最短的信息才是原始的。
输入
第一行是密码表格,包含26个小写字母,依次表示a-z加密后的字母。
第二行是John截获到的通信信息。
输出
包含一行,表示还原后的通信信息。
样例输入
abcdefghijklmnopqrstuvwxyz
abcdab
样例输出
abcdabcd
数据范围
通信长度L<=100000。
题解
这题可以直接暴力。由题目可知密文长度>= ⌊ L / 2 ⌋ \left \lfloor L/2\right \rfloor ⌊L/2⌋,可以把前一半的密文先转换回原文,然后再逐渐匹配,如果失配则立马停止,继续转换,可证明暴力的时间复杂度能够通过1s的时限。
tips:
正解因该是类似于kmp或hash之类的东西。
代码
代码如下
#include<bits/stdc++.h>
using namespace std;
int i,j,n,m,k,l,o,p;
char c[35],ch[35];
char s[100005],ys[100005];
int main()
{
scanf("%s",c+1);
for (i=1;i<=26;i++)
{
ch[c[i]-'a'+1]=i+'a'-1;
}
scanf("%s",s+1);
n=strlen(s+1);
for (i=1;i<=(n-1)/2;i++)
{
ys[i]=s[i];
s[i]=ch[s[i]-'a'+1];
}
for (i;i<=n;i++)
{
ys[i]=s[i];
s[i]=ch[s[i]-'a'+1];
bool bz=1;
for (j=i+1;j<=n;j++)
{
if (s[j]!=s[j-i])
{
bz=0;
break;
}
}
if (bz)
{
for (j=1;j<=i;j++)
{
printf("%c",ys[j]);
}
for (j=1;j<=i;j++)
{
printf("%c",s[j]);
}
return 0;
}
}
for (j=1;j<=n;j++)
{
printf("%c",ys[j]);
}
for (j=1;j<=n;j++)
{
printf("%c",s[j]);
}
}
码风有点丑,请见谅。