链接:https://ac.nowcoder.com/acm/problem/21805
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你两个长度相同的字符串a,b,现在已知b是a编码之后的结果
比如a = "CAT", b = "DOG", 那么D其实是C,O其实是A,G其实是T
现在给你一个字符串c,如果c能够被解码出来,输出c解码后的字符串,如果不能输出@
输入描述:
输入三行,每行一个字符串,长度在50以内
输出描述:
输出一个字符串
示例1
输入
复制
CAT DOG GOD
输出
复制
TAC
示例2
输入
复制
BANANA METETE TEMP
输出
复制
@
示例3
输入
复制
THEQUICKBROWNFOXJUMPSOVERTHELAZYHOG UIFRVJDLCSPXOGPYKVNQTPWFSUIFMBAZIPH DIDYOUNOTICESKIPPEDLETTER
输出
复制
CHCXNTMNSHBDRJHOODCKDSSDQ
备注:
子任务1:|a| <= 10 子任务2:|a| <= 40 子任务3:无限制
分析:我们由字符串a和b的一一对应关系,可以推出每个字母对应的的破解字母,例如给你两个长度相同的字符串a,b,现在已知b是a编码之后的结果
比如a = "CAT", b = "DOG", 那么D其实是C,O其实是A,G其实是T。依据“一一对应”原则可以知道,每个字母只能对应一个破解字母。如果对应多个,那么这肯定是无法破解的。我们可以先统计字符串B中每个字母出现次数,再统计字符串A中每个字母出现次数,由次数从小到大进行排序,检查从A到Z每个stra[i]是否等于strb[i],只要有一个不等于,那么这肯定是不合法的无法破解,直接输出@即可。
如果合法的话,我们再看待破解的字符串中每个字符是否都能在字符串B中找到。那么这个字符串就可以破解了,如果有找不到的,我们还要再分情况讨论。如果在字符串B中能找到25个不同的字母的破解字母,我们就可以推测出剩下一个未出现字母的破解字母,这也是样例3给我们的提示,这样我们同样能够对待破解字符串进行破解,剩下的情况就无法破解了。比如有两个找不到的字母我们就无法推出其中一个字母的破解字母是谁。
#include<stdio.h>
#include<string.h>
typedef long long ll;
const int M=2e2+5;
char stra[M],strb[M],str[M];
ll i,j,k,size1,size2,STA[M],STB[M],sum=0,ta=0,tb=0,t=0;
void mysort(ll *a,ll n);//定义冒泡排序,本来想用sort排序,但总是被WA掉,只好用这个了
int main()
{
scanf("%s",stra);//输入字符串A
scanf("%s",strb);//输入字符串B
size1=strlen(stra);
for(i=0;i<size1;i++)//统计26个字母在字符串A和字符串B中每个字母出现的次数
{
STA[stra[i]]++;STB[strb[i]]++;
}
for(i='A';i<='Z';i++)//统计26个字母有多少个在字符串B中出现过
{
if(STB[i]!=0)
sum++;
}
if(sum==25)//如果只有一个字母没有出现过,我们同样可以推测出没出现的字母和对应的破解字母
{
for(i='A';i<='Z';i++)
{
if(STA[i]==0)
ta=i;
if(STB[i]==0)
tb=i;
}
}
scanf("%s",str);
size2=strlen(str);
mysort(STA,91);
mysort(STB,91);
for(i='A';i<='Z';i++)
{
if(STA[i]!=STB[i])//检查字符串B与字符串A中字母是否一一对应
{
printf("@\n");//只要有一组不对应就直接输出@结束
return 0;
}
}
for(j=0;j<size2;j++)
{
for(i=0;i<size1;i++)
{
if(strb[i]==str[j])//检查待破解字符串中每个字母是否在字符串B中能找到
{
t++;
break;
}
}
}
if(t==size2)//如果都能找到,就进行一一对应破解
{
for(j=0;j<size2;j++)
for(i=0;i<size1;i++)
{
if(strb[i]==str[j])
{
str[j]=stra[i];
break;
}
}
}
else if(sum==25)//如果有找不到的但是能通过已破解的25个字母推测出剩下一个字母,那么也可以
{ //进行破解
for(j=0;j<size2;j++)
for(i=0;i<size1;i++)
{
if(strb[i]==str[j])
{
str[j]=stra[i];
break;
}
else if(str[j]==tb)
{
str[j]=ta;
break;
}
}
}
else//剩下情况就无法破解了直接输出@结束即可
{
printf("@\n");
return 0;
}
for(i=0;i<size2;i++)//输出破解后的字符串
{
printf("%c",str[i]);
}
printf("\n");
}
void mysort(ll *a,ll n)//定义冒泡排序函数
{
int t;
for (int j=0;j<n-1;j++)
{
for (int i=0;i<n-j-1;i++)
{
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
}