观察下面的加法算式:
祥瑞生辉
+ 三羊献瑞
----------------------
三羊生瑞气
(如果有对齐问题,可以参看【图1.jpg】)
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。
答案:1 0 8 5
解析:这个题看起来有点吓人,但是只要认真审题,做起来就没有那么难了,祥瑞生辉代表四个数字组成的一个整数,三羊献瑞代表四个数字组成的一个整数,并且不同的汉字代表不同的数字,祥瑞生辉和三羊献瑞共有一个字(数字)是相同的,四位数+四位数生成了一个五位数,说明三一定是进位1,所以可以确定的是三一定是1,羊、生、瑞、气都是两个加数里面的数,所以这个题不用暴力破解也能解决,可以用全排列的方法来做。先定义一个int类型的数组(c[10]),数组c的初始化方式为:
上图中的数字是数组的下标所对应的汉字(及数字),根据上图下标初始化数组c = {1,0,2,3,4,5,6,7,8,9},c[0]最好等于1,这样可以减少时间复杂度,然后进行全排列的算法,以1开头(即c[0]=1)先把c[5]记录下来(即int=c[5]),根据题目要有瑞字有两个,所以让c[5] = c[3],然后计算祥瑞生辉、三羊献瑞、三羊生瑞气若组成的三个数:
int A = c[0]*1000+c[1]*100+c[2]*10+c[3];
int B = c[4]*1000+c[5]*100+c[6]*10+c[7];
int C = c[0]*10000+c[1]*1000+c[6]*100+c[3]*10+c[8];
若A+B=C则输出c[0],c[1],c[2],c[3]。
代码如下:
public class 三羊献瑞
{
public static void Swap(int[] c,int i,int j) //全排列算法的一部分
{
int tmp = c[i];
c[i] = c[j];
c[j] = tmp;
}
public static void AllPermutation(int[] c,int start) //全排列算法
{
if(start==c.length-1)
{
if(c[0]==1) //因为羊一定代表1,所以只需判断以1开头的排列即可
{
int tmp = c[5]; //先记录下c[5],因为全排列中的数字必须是分别且只出现一次
c[5] = c[3]; //应为有两个瑞字,所以有两个重复数字
int A = c[0]*1000+c[1]*100+c[2]*10+c[3]; //三羊献瑞
int B = c[4]*1000+c[5]*100+c[6]*10+c[7]; //祥瑞生辉
int C = c[0]*10000+c[1]*1000+c[6]*100+c[3]*10+c[8]; //三羊生瑞气
if(A+B==C)
{
System.out.println(c[0]+" "+c[1]+" "+c[2]+" "+c[3]); //输出三羊献瑞
System.exit(0); //退出虚拟机
}
c[5] = tmp; //保证全排列数组中的数分别且只出现一次
}
else //只判断以1开头,其他则不符合要求
{
System.exit(0); //退出虚拟机
}
}
else
{
for(int i=start,t=c.length;i<t;++i)
{
Swap(c,i,start);
AllPermutation(c,start+1);
Swap(c,start,i);
}
}
}
public static void main(String[] args)
{
int[] c = {1,0,2,3,4,5,6,7,8,9}; //1代表羊
AllPermutation(c,0); //全排列算法
}
}
运行结果:
1 0 8 5