• ACM典型试题--古代密码(二)


    1. 题目描述

    古罗马帝国有两种简单的加密算法,第一种按照顺序替换,例如把a-y 分别替换成b-z,
    把z 替换成a,这样可以把VICTORIOUS 替换成WJDUPSJPVT。
    第二种是打乱顺序消息的顺序,例如<2, 1, 5, 4, 3, 7, 6, 10, 9, 8>的含义就是把第二个字
    符放在第一位,而把第一位的字符放到第二位,然后是第5 个字符,第4 个字符,…,可以
    把VICTORIOUS 替换成IVOTCIRSUO。
    后来发现同时使用两种算法, 加密效果更好。可以把VICTORIOUS 替换成
    JWPUDJSTVP。
    题目要求:能不能把第二行中的原文转换为第一行的密文。
    输入格式
    输入包括两行:第一行为加密后的密文,第二行原文。
    输出格式
    如果能够按此方法把第二行的原文转换为第一行的密文,则输出 YES,否则输出NO。
    输入样例
    JWPUDJSTVP
    VICTORIOUS
    输出样例
    YES

    2. 题目分析和算法实现

    首先,要找出规律,第二种方法只会改变每个字符的位置,但是不会影响每个字符在字
    符串中出现的次数。例如A 在原来的字符串中出现3 次,那么通过第二种算法它出现的次
    数还是3 次。第一种算法虽然改变了字符串的内容,但是有些东西没有变化,例如原来字符
    串中的a、b、c 出现的次数分别n1、n2、n3,假设abc 替换def,则d、e、f 出现的次数应
    该是n1、n2、n3。所以只要保证相对位置上的字符出现的次数相同即可实现转换。
    统计输入信息第一行中每个字符出现的次数。使用长度为26 的数组表示,分别表示字
    母A 到字母Z 出现的次数,使用int[] a 表示。
    统计输入信息第二行中的每个字符出现的次数。使用长度为26 的数组表示,分别表示
    字母A 到字母Z 出现的次数,使用int[] b 表示。
    我们循环26 次,第j 次循环中,再循环比较a[(i+j)%26]与b[i]是否相同,如果都相同则

    说明能够转换,输出YES 即可,退出外层循环,否则继续循环。如果26 次循环完之后,没有得到结果,输出NO。

    3. 问题实现及代码分析

    #include<stdio.h>
    #include<string.h>
    void init(), work(), sort(), print();
    int sum1[120], sum2[120], sm1, sm2, count1[120], count2[120], bj;
    char s1[120], s2[120];
    int main() {
    	init();
    	work();
    	return 0;
    }
    void init() {
    	int i;
    	for(i = 1; i <= 119; ++i) {
    		sum1[i] = sum2[i] = count1[i] = count2[i] = 0;
    	}
    	sm1 = 0;
    	sm2 = 0;
    	gets(s1);
    	gets(s2);
    }
    void work() {
    	int i;
    	for(i = 0 ; i <= strlen(s1) - 1; ++i){
    		++sum1[s1[i] - 'A' + 1];
    		++sum2[s2[i] - 'A' + 1];
    	}
    	for(i = 1; i <= 26; ++i) {
    		if(sum1[i])
    			count1[++sm1] = sum1[i];
    		if(sum2[i])
    			count2[++sm2] = sum2[i];
    	}
    	if(sm1 != sm2) {
    		bj = 1;
    		print();
    	}
    	else {
    		sort();
    		bj = 2;
    		for(i = 1; i <= sm1; ++i)
    			if(count1[i] != count2[i]) {
    					bj = 1;
    				break;
    			}
    			print();
    	}
    }
    void print() {
    	if(bj == 1) printf("NO
    ");
    	else
    		printf("YES
    ");
    }
    void sort() {
    	int i, j, ch;
    	for(i = 1; i <= sm1; ++i )
    		for(j = i + 1; j <= sm1; ++j ) {
    			if(count1[i] > count1[j]) {
    				ch = count1[i];
    				count1[i] = count1[j];
    				count1[j] =ch;
    			}
    			if(count2[i] > count2[j]) {
    				ch = count2[i];
    				count2[i] = count2[j];
    				count2[j] =ch;
    			}
    		}
    }

    4.结果



  • 相关阅读:
    HTML5小时钟
    简单画板
    li样式不显示使用overflow:hidden导致Li前面点、圈等样式不见
    Dede 列表页 缩略图 有显示无则不显示
    CSS3的position:sticky介绍
    json 包含字段及函数的写法
    PHP+Ajax 异步通讯注册验证
    find命令结合cp bash mv 命令使用的4种方式
    markdown完整语法规范3.0+编辑工具介绍
    几款 ping tcping 工具总结
  • 原文地址:https://www.cnblogs.com/whzhaochao/p/5023489.html
Copyright © 2020-2023  润新知