*吸血鬼数字是指位数为偶数的数字,可以由一堆数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排列。以两个0结尾的数字是不允许的
例如,下列数字都是吸血鬼数字
1260=21*60 1827=21*87 2187=27*81
写一个程序,找出所有4位的吸血鬼数字*
void test(){
int count = 0,num=0;
int from,to,val;
for(int i=10;i<100;i++) {
from = Math.max(1000/i, i+1);//就是i*j>=1000的意思,在i已知的情况下,j的最小值基本已经确定,从这个值开始内循环比较高效。
to = Math.min(10000/i, 100);
for(int j=from;j
val = i*j;
if(val%100==0 || (val-i-j)%9!=0) continue;
count++;
char[] cval = String.valueOf(val).toCharArray();
char[] ij = (String.valueOf(i)+String.valueOf(j)).toCharArray();
Arrays.sort(cval);
Arrays.sort(ij);
if(Arrays.equals(cval,ij)){
num++;
System.out.print("第"+num+"组吸血鬼数字:");
System.out.println(i+"*"+j+"="+val);
}
}
}
System.out.println("总共比较"+count+"次");
}
}
关于算法的解释,来自网友MT502
假设val = 1000a + 100b + 10c + d, 因为满足val = x * y, 则有x = 10a + b, y = 10c + d
则val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c), 所以val - x - y能被9整除。
所以满足该条件的数字必定能被9整除,所以可以直接过滤其他数字。
我准许做一下
x*y = val = 1000a + 100b + 10c + d;
我们假设
x = 10a + b, y = 10c + d
则
x*y-x-y
= val - x-y
= (1000a + 100b + 10c + d) - (10a+b) - (10c +d) = 990a + 99b + 9c
= 9 * (110a + 11b + c);
对于别的组合可能性,结果一样,比如
x=10c+a; y=10d+b;
x*y-x-y
= val - x-y
= (1000a + 100b + 10c + d) - (10c+a) - (10d +b) = 999a + 99b -9d
= 9 * (110a + 11b -d);
当然也能被9整除了