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,,
来源:https://blog.csdn.net/u013501457/article/details/32730465