当前位置: 代码迷 >> 综合 >> poj 2159 Ancient Cipher
  详细解决方案

poj 2159 Ancient Cipher

热度:30   发布时间:2024-01-11 17:08:43.0

这题主要应该就是理解题意的问题,我的确是把题目理解错了,WA了三次,每次都以为一定是正确的,后来看了别人的解释才知道是题目理解错了(竟然还看到了别人的结题报告也有错的。。。),另外就是学会了用STL的sort快排,很方便,在<algorithm>头文件里面,这说明了一定要自己会写排序,但是不一定每次都是自己写函数,有N多好的函数别人已经写好了,你只用知道什么时候该用就可以了。。。但是自己也要会写(万一比赛不允许用库函数)


开始错误的想法:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>using namespace std;int main()
{char input[102],source[102];scanf("%s%s",input,source);//printf("\n%s\n%s\n",input,source);int i;for(i=0;i<strlen(input);i++){if(input[i]=='A')input[i]='Z';elseinput[i]=input[i]-1;}// 标准库自带排序函数sort(ip_start,ip_end) 对某连续的地址段的对象内容进行升序快排(从小到大),<algorithm>sort(input,input+strlen(input));sort(source,source+strlen(source));//printf("\n%s\n%s\n",input,source);	//okif(strcmp(input,source)==0)printf("YES\n");elseprintf("NO\n");return 0;
}
关键就在于满足“置换”的只要是同字母就OK了,题目中给的一组测试数据是误导人的,应该用出现的次数来写,而不是每个字母的位移一定相同。


看了别人的解释:(注意下面的 For example, applying substitution 。。。,代表不是普适的,只是举的一个特例

substitution cipher (置换密码):

Substitution cipher changes all occurrences of each letter to some other letter. Substitutes for all letters must be different.For some letters substitute letter may coincide with the original letter. For example, applying substitution cipher that changes all letters from 'A' to 'Y' to the next ones in the alphabet, and changes 'Z' to 'A', to the message "VICTORIOUS" one gets the message "WJDUPSJPVT".

“移位”只是置换密码的一种,只要满足“Substitutes for all letters must be different.”就是置换了,比如

A->B

C->H

Z->D

对于这道题,input:

AAABB
CCCEE

应输出

YES

所以明文与密文的“字母频率的数组”应该是一样的,即明文中某字母出现8次,密文中也必须有某个字母出现8次。

所以字母种类,字母频率同时相等时,即被破解。

permutation cipher(排列密码):

Permutation cipher applies some permutation to the letters of the message. For example, applying the permutation <2, 1, 5, 4, 3, 7, 6, 10, 9, 8> to the message "VICTORIOUS" one gets the message "IVOTCIRSUO".

明文随机排列,所以字母种类和频率都不变。

对于这道题,排列密码考虑和不考虑对解题无影响!”



正确的代码


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>using namespace std;int input[26],source[26];int main()
{char temp[102];scanf("%s",temp);int i;for(i=0;i<strlen(temp);i++){input[temp[i]-'A']++;}scanf("%s",temp);for(i=0;i<strlen(temp);i++){source[temp[i]-'A']++;}// 标准库自带排序函数sort(ip_start,ip_end) 对某连续的地址段的对象内容进行升序快排(从小到大),<algorithm>sort(input,input+26);sort(source,source+26);for(i=0;i<26;i++)if(input[i]!=source[i]){printf("NO\n");return 0;}printf("YES\n"); return 0;
}