题目链接:P1071 潜伏者
题解: 建议看3.0的参考代码。。。。。。
注意点:
- 加密信息的字母要都在原信息中出现;有没有出现的输出Failed;
- 原信息或加密信息必须都出现26个字母;小于26个字母输出Failed;
- 每个字母只能一一对应,不能出现多对一或一对多的情况;出现了则输出Failed;
解释:用一个结构体或pair类型来存储一一对应的字母,方便由加密信息来找原字母;查找原信息中是否存在加密字母可以用for循环来,也可以直接调用string的find函数来找,找不到时返回string::nops; 用vis数组标记是否已经存储过该加密信息,没有存储过则将该组信息存储到结构体或pair中,并令计数器++来保存够不够26个字母;若存储过则看看加密信息对应的原文是否相同,不同则直接Failed结束;相同则再将其存储起来。最后检查一下是否够26个字母,直接使用计数器和26比较即可,若够的话,则将待翻译的密文一一对应的翻译出来;
--------------------------------------------------------------------------------分割线-------------------------------------------------
细节:本来检查26个字母用的是check函数:后来发现其实直接再存储时就进行计数器++即可,汗!!!
bool check()
{
for(int i = 0; i < s.size(); i++)
pos[ss[i].first - '0'] = 1;
for(int i = 'A' - '0'; i <= 'Z' - '0'; i++)
if(pos[i] == 0) return false;
return true;
}
参考代码:1.0 用pair实现,可以用struct结构体实现!!!都可以的!
string的find函数找不到返回string::npos;
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<char, char> PP;
string str, s, t;
PP ss[110];
int k, pos[100], j;
bool vis[100];
PP get_c(char c)
{
for(int i = 0; i < s.size(); i++)
if(ss[i].first == c) return ss[i];
}
bool check()
{
for(int i = 0; i < s.size(); i++)
pos[ss[i].first - '0'] = 1;
for(int i = 'A' - '0'; i <= 'Z' - '0'; i++)
if(pos[i] == 0) return false;
return true;
}
int main()
{
cin >> s >> str >> t;
for(int i = 0; i < s.size(); i++)
{
if(str.find(s[i]) == string::npos)
{
cout << "Failed" << endl;return 0;
}
if(vis[s[i] - '0'])
{
PP r = get_c(s[i]);
if(r.second != str[i]) {cout <<"Failed"<<endl; return 0;}
else ss[i] = {s[i], str[i]};
}
else ss[i] = {s[i], str[i]}, vis[s[i] - '0'] = true, j++;
}
//直接j++计数就行,当然check函数也是对的
//if(!check()) {cout << "Failed" << endl;return 0;}
if(j < 26) {cout << "Failed" << endl;return 0;}
for(int i = 0; i < t.size(); i++)
{
PP r = get_c(t[i]);
cout << r.second;
}
return 0;
}
参考代码2.0: 结构体实现,就改了一下;string的查找改了一下;
typedef struct Node
{
char first, second;
}PP;
完整代码:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct Node
{
char first, second;
}PP;
string str, s, t;
PP ss[110];
int k, pos[100], j;
bool vis[100];
PP get_c(char c)
{
for(int i = 0; i < s.size(); i++)
if(ss[i].first == c) return ss[i];
}
int Find(char c)
{
for(int i = 0; i < str.size(); i++)
if(str[i] == c) return 1;
return 0;
}
int main()
{
cin >> s >> str >> t;
for(int i = 0; i < s.size(); i++)
{
if(!Find(s[i]))
{
cout << "Failed" << endl;return 0;
}
if(vis[s[i] - '0'])
{
PP r = get_c(s[i]);
if(r.second != str[i]) {cout <<"Failed"<<endl; return 0;}
else ss[i] = {s[i], str[i]};
}
else ss[i] = {s[i], str[i]}, vis[s[i] - '0'] = true, j++;
}
if(j < 26) {cout << "Failed" << endl;return 0;}
for(int i = 0; i < t.size(); i++)
{
PP r = get_c(t[i]);
cout << r.second;
}
return 0;
}
参考代码:3.0 struct实现,相较于前两个更好理解,清晰。。。。
#include <iostream>
#include <cstring>
using namespace std;
char before[110],after[110],word[110];
int vis[27];
struct Node
{
char b,a;
};
Node T[27];
Node get_c(char c)
{
for(int i = 0; i < 26; i++)
if(T[i].a == c)
return T[i];
}
int main()
{
cin >> after >> before >> word;
for(int i=0;i<strlen(before);i++)
{
if(vis[before[i]-'A']==1)
{
if(T[before[i] - 'A'].a != after[i])
{
cout<<"Failed"<<endl;
return 0;
}
else continue;
}
T[before[i] - 'A'] = {before[i], after[i]};
vis[before[i]-'A']=1;
}
for(int i=0;i<26;i++)
{
if(!vis[i])
{
cout<<"Failed"<<endl;
return 0;
}
}
for(int i=0;i<strlen(word);i++)
{
Node t = get_c(word[i]);
cout << t.b;
}
return 0;
}