【题目链接】
ybt 1855:【09NOIP提高组】潜伏者
OpenJudge NOI 1.7 11:潜伏者
洛谷 P1071 [NOIP2009 提高组] 潜伏者
【题目考点】
1. 字符串
2. ASCII码
【解题思路】
因为题中指明了:每个字母只对应一个唯一的“密字”,不同的字母对应不同的“密字”。因此明文字母和密文字母为一一对应的关系。
设数组ori与enc,初值都为’\0’。ori[i]指密文字母i对应的明文字母,enc[i]指明文字母i对应的密文字母。每找到新的一对对应关系:明文A对应密文B,则需要先检查明文A是否已经有对应的密文字母(enc[A]是否不为’\0’),以及密文B是否有对应的明文字母(ori[B]是否不为’\0’)。
- 如果二者都没有对应的字母,那么建立明文A与密文B的对应关系,让enc[A] = B,ori[B] = A。每建立一对关系,做一次计数。
- 如果A或B已经存在与其对应的字母,而且对应关系不为“明文A对应密文B”,那么输出Failed。
由于题目中有要求:如果发现存在某个(或某些)字母在原信息中没有出现,则破译失败。所以每个密文字母都要有与其对应的明文字母,对应关系数量必须得等于26。
最后统计关系数量,如果达到26,则使用已经构建好的明文密文关系做字符串解密。如果关系数量小于26,则输出Fail。
【题解代码】
解法1:
#include<bits/stdc++.h>
using namespace std;
#define N 105
int main()
{
char s_e[N], s_o[N], s_n[N];//s_e:加密后字符串 s_o:原字符串 s_n:待加密字符串
char ori[128] = {}, enc[128] = {};//ori[i]:ASCII码为i的加密字符的原字符 enc[i]:ASCII码为i的原字符对应的加密字符 初值都为'\0'
cin >> s_e >> s_o >> s_n;
int l1 = strlen(s_e), l2 = strlen(s_n), cn = 0;//cn:已经确定的加密关系的个数
for(int i = 0; i < l1; ++i)
{
if(ori[s_e[i]] == '\0' && enc[s_o[i]] == '\0')//如果不存在s_e[i]对应的明文,同时不存在s_o[i]对应的密文
{//建立对应关系:明文s_o[i]对应密文s_e[i]
ori[s_e[i]] = s_o[i];
enc[s_o[i]] = s_e[i];
cn++;
}
else if(ori[s_e[i]] != s_o[i] || enc[s_o[i]] != s_e[i])//如果已有对应关系,且对应关系不为明文s_o[i]对应密文s_e[i]
{
cout << "Failed";
return 0;
}
}
if(cn != 26)//如果对应关系不足26对
{
cout << "Failed";
return 0;
}
for(int i = 0; i < l2; i++)//解密s_n字符串
cout << ori[s_n[i]];
return 0;
}