HDU1287 破译密码

来源:互联网 发布:互盾数据恢复软件 编辑:程序博客网 时间:2024/06/05 05:22
Problem Description
有个叫“猪头帮”的国家,采用一种简单的文法加密,他们所用的语言里面只有大写字母,没有其他任何字符;现在还知道他们加密的方法是:只用一个大写字母和原文进行异或运算生成密文。请你帮忙解开。

Input
有若干组,每组输入有2行,第一行整数N表示有N个密文,接着一行有N个整数分别表示N个密文

Output
输出仅有大写字母组成的原文。


Sample Input
3017 6 9 8 3 0 1 6 7 4 5 10 11 8 9 14 15 12 13 18 19 16 17 22 23 20 21 26 27 24

Sample Output
SDKJABCDEFGHIJKLMNOPQRSTUVWXYZ

出看这题有点奇怪,莫名其妙,后来看懂了,用于转化的字符没有告诉你,转化长度没有告诉你,只有转化后的密文,想了很久,想了一个暴力枚举的办法,数组开了1000,还怕不够呢,结果居然过了,其实想想也是,26x26 的范围,能出多少数呢,


用一个二重循环,和一个数组a[27][40](i^j最大为31  )记录下每一个i(1-26)对j(1-26)异或的值,并且吧a[i][i^j]=j;其余空位置为0,这样,就记录了所有的i^j和对于的i,然后对于输入的数据,从i=1-26检查,如果所有数据的对应位a[i][b[j]]不等于,即存在,则当前i就是转化的大写字母,然后输出就简单了,记录当前i值,然后对应输出a[i][b[j]]的值(存的是j的值嘛) 输出j+'A'-1;就好了,

说的不太明白,就是用对于i和i^j的值映射  然后映射的地址存放  j  因为检查过  所有固定的  i  ^  j(1-26)都没有重复,对于每一个i, j的变化都有唯一对应的值


贴上代码说吧


#include<stdio.h>int main(){int a[27][40]={0},b[1000],i,j,n,f;for(i=1;i<27;i++)for(j=1;j<27;j++)a[i][i^j]=j;while(~scanf("%d",&n)){for(i=1;i<=n;i++)scanf("%d",&b[i]);for(i=1;i<27;i++){f=1;for(j=1;j<=n;j++)if(a[i][b[j]]==0){f=0;break;}if(f==1){f=i;break;}}for(j=1;j<=n;j++)printf("%c",a[f][b[j]]+'A'-1);printf("\n");}}

AC,,


0 0
原创粉丝点击