东师大一教育技术学学生,最近在做NENUOJ上的题目,由于担心查重不提供代码,这里提供一个解决古代密码的题的思路
题目是这样的:
古罗马帝王有一个包括各种部门的强大政府组织。其中有一个部门就是保密服务部门。为了保险起见,在省与省之间传递的重要文件中的大写字母是加密的。当时最流行的加密方法是替换和重新排列。
替换方法是将所有出现的字符替换成其它的字符。有些字符会碰巧替换成它自己。例如:替换规则可以是将A 到 Y替换成它的下一个字符,将Z替换成 A,如果原词是 VICTORIOUS 则它变成 WJDUPSJPVT。
排列方法改变原来单词中字母的顺序。例如:将顺序 <2, 1, 5, 4, 3, 7, 6, 10, 9, 8> 应用到 VICTORIOUS 上,则得到IVOTCIRSUO。
人们很快意识到单独应用替换方法或排列方法,加密是很不保险的。但是如果结合这两种方法,在当时就可以得到非常可靠的加密方法。所以,很多重要信息先使用替换方法加密,再将加密的结果用排列的方法加密。用两种方法结合就可以将VICTORIOUS 加密成JWPUDJSTVP。
考古学家最近在一个石台上发现了一些信息。初看起来它们毫无意义,所以有人设想它们可能是用替换和排列的方法被加密了。人们试着解读了石台上的密码,现在他们想检查解读的是否正确。他们需要一个计算机程序来验证她,你的任务就是写这个验证程序。
输入要求:
输入有两行。第一行是石台上的文字。
文字中没有空格,并且只有大写英文字母。
第二行是被解读出来的加密前的文字。
第二行也是由大写英文字母构成的。这两行字符数目的长度都不超过计划100。
输出要求:
如果第二行经过某种加密方法后可以产生第一行的信息,输出 YES,否则输出NO。
样例输入如下:
JWPUDJSTVP
VICTORIOUS
样例输出:
YES
我们要明确,加密方式应该是统一的,也就是说如果我现在手里的是一个abc,我现在如果排列方式是321,而替换的是后一位
那么首先,我们将ABC变成BCD,而排列后变成DCB
我们要检测的就是DCB和ABC通过某种方式可以相互转化
怎么检测呢?
如果我们现在去看一下ABC和DCB我们可以发现这两个字符串的唯一关系就是都由三个相邻的字母构成,那么我再进一步去思考,我要确定能不能转化,我只要发现ABC和DCB都是由三个相邻字母构成就可以相互转换。
那我可以拿一个数组用来放第一个字符串的每种字母(一共26个)的数量。
第二个也一样。
代码(c++)如下:
int len = firststring.length();//stores the length of the first string
//the two string's length are equal so we don't need another
int f[30]//store the number of each letter in first string
int s[30]//store the number of each letter in second string
for(int i=0;i<len;i++){
f[firststring[i]-'A']++;
//the number of characters minus A indicates the position in the alphabet
s[secondstring[i]-'A']++;
}
然后我们只需要从头检查是不是两个数组是否存在对应关系就可以完成检测
可以设置一个二重循环,一个表示替换一个表示排列,只要检测到不匹配就重新来,如果完美匹配只需一次就输出“YES”并跳出循环
如果需要具体代码可以参考这两位大佬的博客
(15条消息) 古代密码_标准字头密码_Florence_Janie的博客-优快云博客
OpenJudge 1.13-51:古代密码 题解 - octal_zhihao - 博客园 (cnblogs.com)