首先介绍下吸血鬼数字的特性:
一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。后面是两个0的不算,比如3000=50*60
举例:
*15*93=1395 21*60=1260 21*87=1827*
代码实现
import java.util.Arrays;
/**
* 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。
* 比如 1395 =15 * 93
*/
public class Vampire {
public static void main(String[] arg) {
String[] ar_str1, ar_str2;
int sum = 0;
int from;
int to;
int i_val;
int count = 0;
// 双重循环穷举,i从10——99,j根据i的值来进行变换,满足i*j在4位数范围内
for (int i = 10; i < 100; i++) {
//j=i+1避免重复
//from到to是保证i*j的值在1000-10000之间,保证是4位数
from = Math.max(1000 / i, i + 1);
to = Math.min(10000 / i, 100);
for (int j = from; j < to; j++) {
i_val = i * j;
//下面具体分析为何要把(i_val - i - j) % 9 != 0的数字去掉
if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) {
continue;
}
count++;
ar_str1 = String.valueOf(i_val).split("");
ar_str2 = (String.valueOf(i) + String.valueOf(j)).split("");
Arrays.sort(ar_str1);
Arrays.sort(ar_str2);
if (Arrays.equals(ar_str1, ar_str2)) {// 排序后比较,为真则找到一组
sum++;
System.out.println("第" + sum + "组: " + i + "*" + j + "="
+ i_val);
}
}
}
System.out.println("共找到" + sum + "组吸血鬼数");
System.out.println(count);
}
}
分析:
假设val = 1000a + 100b + 10c + d, 拆分成val = x * y
而x是a、b、c、d中两个的线性组合,y是另两个的线性组合,系数分别是10和1
则val-x-y
=val-m1*a-m2*b-m3*c-m4*d //m1\m2\m3\m4 是10或者是1
=1000a + 100b + 10c + d-m1*a-m2*b-m3*c-m4*d
=(1000-m1)a+(100-m2)b+(10-m3)c+(1-m4)d
1000-m1等900或者999,能被9整除
100-m2等90或者99,能被9整除
10-m3等0或者9,能被9整除
1-m4等-9或者0,能被9整除
所以(1000-m1)a+(100-m2)b+(10-m3)c+(1-m4)d能被9整除
得到val-x-y能被9整除
文章参考:http://blog.csdn.net/java2000_net/archive/2009/01/23/3851203.aspx