题解:P13311 [GCJ 2012 Qualification] Speaking in Tongues
题目大意
通过样例与题面破译出输入的字符串。
思路
依题意得,每一个字母都对应了另一个字母,也就是说密匙只有一个,字母之间一一对应。那么就可以研究样例得出结论了。
研究方法无非就是写一个程序,排列好一一对应的字母,然后输出这个数组。
但是你会发现有一些字母没有被映射,这时由题面就很容易可以得出剩下字母的对应字母。
研究过程的代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
char a[101];
int h[31];
int main()
{
for(int j=1;j<=3;j++)
{
string s1,s2;
getline(cin,s1);
getline(cin,s2);
for(int i=0;i<s1.size();i++)
{
if(s1[i]!=' ')
{
a[s1[i]-'a'+1]=s2[i];
h[s2[i]-'a'+1]=1;//这是用来判断哪一些字母没有被映射的桶排数组。
}
}
}
cout<<"a[27]={'0',";
for(int i=1;i<=26;i++)
{
if(i!=26) cout<<"'"<<a[i]<<"',";
else cout<<a[i]<<"};\n";
}
for(int i=1;i<=26;i++)
{
if(!h[i]) cout<<char(i+'a'-1)<<" ";
}
}
/*
排列好的样例有助于输入。
ejp mysljylc kd kxveddknmc re jsicpdrysi
our language is impossible to understand
rbcpc ypc rtcsra dkh wyfrepkym veddknkmkrkcd
there are twenty six factorial possibilities
de kr kd eoya kw aej tysr re ujdr lkgc jv
so it is okay if you want to just give up
*/
于是我们就得到了密匙数组。接下来的就很简单了。不过注意在用 getline 读取字符串时要注意前面的 cin,如果有则要用 cin.ignore()。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
char a[27]={'0','y','h','e','s','o','c','v','x','d','u','i','g','l','b','k','r','z','t','n','w','j','p','f','m','a','q'};
int n;
int main()
{
cin>>n;
cin.ignore();//防止getline读入换行符。
for(int i=1;i<=n;i++)
{
string s;
getline(cin,s);
cout<<"Case #"<<i<<": ";
for(int j=0;j<s.size();j++)
{
if(s[j]!=' ') cout<<a[s[j]-'a'+1];
else cout<<' ';
}
cout<<endl;
}
}