Description
ACM小组最近开始出现一些内部矛盾,主要原因是Samsara,Sowicm与Gestapolur对小组的命名产生了分歧,但是Samsara和 Sowicm是绝对不会屈服于Gestapolur,所以他们暗中联系怎样打败Gestapolur,但是为了不让Gestapolur发现他们的目的, 他们希望会编程的你用他们的规则对信息进行加密,以利于他们更完美的战胜Gestapolur。
Input
输入包含约100组数据,每组数据包括四行,第一行和第二行有两个长度相同的字符串S1和S2,分别表示明文到密文的对应关系,第一行为明文字符串S1, 第二行为对应加密关系字符串S2,第三行为需要加密的明文字符串S3,第四行为需要解密的密文字符串S4。 (1<=length(S1)=length(S2),length(S3),length(S4)<255)
读入以EOF结束。
Output
每组数据输出两行,每组第一行输出S3对应的密文字符串,第二行输出S4对应的明文字符串,对每一行输出,如果出现未给出的明文到密文的对应关系或者对应关系有误(一个明文对应多个密文或多个明文对应一个密文)就输出“Wrong”(不包括引号)。
Sample Input
abcde
fghij
anc
fhi
Sample Output
Wrong
acd
Hint
数据中给出所有字符串只包含数字及大小写字母。
Source
CSU Monthly 2011 Dec.
AC代码:
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main()
{
bool flag1[300], flag2[300];
string s1, s2, s3, s4, a1, a2;
while (cin >> s1 >> s2 >> s3 >> s4)
{
memset(flag1, 0, sizeof flag1);
memset(flag2, 0, sizeof flag2);
for (string::size_type i = 0; i != s1.size(); i++)
{
if (s1.find(s1[i]) != s1.rfind(s1[i]))//判断s1中是否有重复字符
if (s2[s1.find(s1[i])] != s2[s1.rfind(s1[i])])
flag1[i] = true;
if (s2.find(s2[i]) != s2.rfind(s2[i]))//判断s2中是否有重复字符
if (s1[s2.find(s2[i])] != s1[s2.rfind(s2[i])])
flag2[i] = true;
}
for (string::size_type i = 0; i != s3.size(); i++)
{
if (s1.find(s3[i]) != string::npos && !flag1[s1.find(s3[i])])
a1.push_back(s2[s1.find(s3[i])]);
else
{
a1 = "Wrong";
break;
}
}
for (string::size_type i = 0; i != s4.size(); i++)
{
if (s2.find(s4[i]) != string::npos && !flag2[s2.find(s4[i])])
a2.push_back(s1[s2.find(s4[i])]);
else
{
a2 = "Wrong";
break;
}
}
cout << a1 << endl;
cout << a2 << endl;
a1.clear();
a2.clear();
}
return 0;
}
思路分析:
用四个string存四个输入,两个bool数组分别处理明文和密文中的重复字符。
两个输出实际上是等价的,能解决第一个输出,第二个输出也能采用同样的方法。
以找出s3对应的输出为例:
通过string的find函数和rfind函数来判断s1的当前字符是否有重复。如果重复,两函数返回的索引值必然是不相等的。然后判断s2在两个索引值的字符是否相同,如果不同,说明是“真的”出现了一对多的情况,对该字符进行标记。
在求s3对应的输出a1时,先用find函数判断当前s3中的字符是否存在于s1中,且是否被标记。如果存在且未被标记就将s2中对应位置的字符存入a1中。只要任一条件不满足,a1即为Wrong。
s2和s4同理。
这题一开始分析的不是很清楚,主要是这段话:
对每一行输出,如果出现未给出的明文到密文的对应关系或者对应关系有误(一个明文对应多个密文或多个明文对应一个密文)就输出“Wrong”(不包括引号)。
一开始的想法是只要s1中出现重复字符s3对应的输出就给Wrong,s2、s4同理。交完果断WA了。之后想只要s3中出现的字符在s1中不重复,就能输出对应密文,s2、s4同理。依然是WA。交到怀疑人生后拿别人的AC代码测试了一遍终于发现了隐藏的问题:即使s3中出现了s1里的重复字符,也有可能不输出Wrong。只要重复字符对应的密文也是相同的即可,例如dd对ii。
估计我还需要重新学学语文Orz