HDU1287 破译密码

喜夏-厌秋 提交于 2019-12-02 14:37:15

Problem Description

有个叫“猪头帮”的国家,采用一种简单的文法加密,他们所用的语言里面只有大写字母,没有其他任何字符;现在还知道他们加密的方法是:只用一个大写字母和原文进行异或运算生成密文。请你帮忙解开。

 

Input

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

 

Output

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

 

 

Sample Input

30 17 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 OutputSDKJABCDEFGHIJKLMNOPQRSTUVWXYZ

 

出看这题有点奇怪,莫名其妙,后来看懂了,用于转化的字符没有告诉你,转化长度没有告诉你,只有转化后的密文,想了很久,想了一个暴力枚举的办法,数组开了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,,

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!