Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

题解 洛谷P1071【潜伏者】

KGB1331 2019-09-11 19:17:00 阅读数:9 评论数:0 点赞数:0 收藏数:0

题目链接:https://www.luogu.org/problem/P1071

题意概括:给你一段原来截获的英文密码和与之对应的明文,如果密码表非F*A法,输出"Failed" ,否则翻译现在给你的一句密文并输出。(所有字母均为大写)

 

有两种情况视为密码表非法:

1、 所有信息扫描完毕,但发现有字母在原信息中没有出现(密码表脱漏)。

2、 扫描中发现掌握的信息里有明显的自相矛盾或错误(密码表错乱)。

这道题主要思想可以利用数组打表,首先我们定义一个数组code作为密码表

然后进行密码表制作,比如一个密文是“DDYAKIOI”,明文是“SSDPOLKL”(首先声明一点,这只是为了便于理解写的短样例,这个样例实际上已经非法了)

可见code['D'](即code[68])为'S',code['Y']为'D',以此类推。

现有密文为"DOAI",根据一对一原则,翻译出来就是"SKPL"。

下面详细解释一下两种非法情况:

一、密码表脱漏

很好理解,就是有的密文位没有相对应的明文字母。排除方法:因为本题常数较小,考虑使用直接扫描的方法判断

二、密码表错乱

这种情况又分为两种小情况:一对多和多对一

一对多:一个密文位对应多个明文字母。排除方法:压入明文制表过程中判断,发现与当前占位被不同字母抢占则判定非法

多对一:多个密文对应一个明文字母。排除方法:全表从头至尾扫描,发现与当前明文占位不同明文相同的则判定非法

(此图大雾)

接下来是愉快的贴代码时间,是好孩子的话就不要复制题解呢……(微笑)

 //Stand up for the faith!
 #include<bits/stdc++.h>
 using namespace std;
 #define ll long long
 
 char myst[],word[];
 char sent[],code[];
 //分别代表密文、明文、需译语句、密码表 
 signed main(void)
 {
     scanf("%s%s",myst,word);
     int len1=strlen(myst);
     int len2=strlen(word);
     for(int i=;i<=;i++) code[i]='\0'; //初始化密码表,方便判断脱漏 
     if(len1!=len2||len1<) //初步判断 
     {
         puts("Failed");return ;
     }
     /*此处明确几点:
     1、如果密文和明文长度不等,100%无法一一对应,视为非法 
     2、如果长度少于26,一定无法A-Z全部对应,直接非法 
     3、如果长度多于26,不一定非法(比如有两次等价对应)*/
     for(int i=;i<len1;i++)
     {
         if(code[myst[i]]>='A'&&code[myst[i]]<='Z'&&code[myst[i]]!=word[i]) 
         //判断不同字母对应相同密字(此前已有其他不同的字母占位) 
         {
             puts("Failed");return ;
         }
         for(int j='A';j<='Z';j++)
         {
             if(code[j]==word[i]&&j!=myst[i])
             //判断相同字母对应不同密字(在不同占位上含有相同的字母) 
             {
                 puts("Failed");return ;
             }
         }
         code[myst[i]]=word[i];
     }
     for(int i='A';i<='Z';i++)
     {
         if(code[i]=='\0') //判断是否有字母没有出现 
         {
             puts("Failed");return ;
         }
     }
     scanf("%s",sent);
     int len=strlen(sent);
     for(int i=;i<len;i++)
     {
         cout<<code[sent[i]]; //逐个输出对应字母
     }
 } 

 

作者:KGB1331

2019-09-11 19:13:36

版权声明
本文为[KGB1331]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/KGB1331/p/11508161.html