信息学奥赛一本通 1855:【09NOIP提高组】潜伏者 | OpenJudge NOI 1.7 11:潜伏者 | 洛谷 P1071 [NOIP2009 提高组] 潜伏者

【题目链接】

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值