算法刷题记录:[NOIP2009]潜伏者
题目链接
https://ac.nowcoder.com/acm/contest/19306/1051
题目分析
用a、b进行映射。map或者模拟都可以。
注意两点即可:
- a中的所有字母必须在b中出现,那么我们统计b中的所有字符再来判断a。
- a、b不能矛盾,将b[i]储存在idx_a上即可。
最后破译的时候,因为a、c同为密文,所以用idx_c映射回去就行。
思考进行映射或者映射回去的时候,要想清楚:数组idx的属性代表什么,a[i]的属性又是什么。
只有属性相同,才能来回映射。
AC代码
// 1.原信息的内容与加密后所的内容均由大写字母‘A’—‘Z’构成
// 2.每个字母都有密字,加密过程就是将原信息替换成密字
// 3.不同字母对应不同密字
// 利用加密前的信息和加密后的信息获取密钥
// 步骤:于原信息中的字母x,找到其在加密信息中的对应大写字母y,并认为在密码里y是x的密字
// 停止状态
// 1.所有信息扫描完毕, 26个字母在原信息中均出现过并获得了相应的“密字”
// 2.所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出现。
// a的所有字母必须出现在b中
// 3.扫描中发现掌握的信息里有明显的自相矛盾或错误
#include <iostream>
using namespace std;
string a, b, c, ans;
char st1[26];
bool st2[26];
int main()
{
cin >> a >> b >> c;
if (a.size() != b.size()) { cout << "Failed"; return 0; }
if (a.size() == 1 && b.size() == 1 && a[0] == 'A' && b[0] == 'A')
{ cout << "Failed"; return 0; }
bool flag = true;
// a的所有字母必须在b中出现,统计b的所有字母,判断a的字母是否出现
for (int i = 0; i < b.size(); ++ i)
st2[b[i] - 'A'] = true;
for (int i = 0; i < a.size(); ++ i)
if (!st2[a[i] - 'A']) { flag = false; break; }
if (flag)
{
// 将b[i]记录在a[i]上
for (int i = 0; i < b.size(); ++ i)
{
// if (a[i] == b[i]) { cout << "Failed"; return 0; }
int pos_a = a[i] - 'A';
if (st1[pos_a] != '\0' && (st1[pos_a] == b[i])) continue;
if (st1[pos_a] != '\0') { flag = false; break; }
st1[pos_a] = b[i];
}
}
if (!flag) { cout << "Failed"; return 0; }
else
{
for (int i = 0; i < c.size(); ++ i)
ans.push_back(st1[c[i] - 'A']);
cout << ans;
}
}
本文来自博客园,作者:想个昵称好难ABCD,转载请注明原文链接:https://www.cnblogs.com/ClockParadox43/p/17432993.html