《Thinking in JAVA》第四章第十题
原题:
吸血鬼数字是指位数为偶数的数字,可以由一堆数字想乘而得到。而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列的数字都是“吸血鬼”数字:
1260=21*60
1827=21*87
2187=27*81
写出一个程序,找出4位数的所有吸血鬼数字
在寻找解决方法的时候,看到了https://blog.csdn.net/java2000_net/article/details/3851203 同学提供的一种特别的方法很精巧,在此纪录一下
代码如下:
package cheapt4;
import java.util.Arrays;
/**
* 吸血鬼数字,高效率版本.<br>
* 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。<br>
* 比如 1395 =15 * 93
*
* @author
*/
public class practice10 {
public static void main(String[] arg) {
String[] ar_str1, ar_str2;
int sum = 0;
int from;
int to;
int i_val;
int count = 0;
// 双重循环穷举
for (int i = 10; i < 100; i++) {
// j=i+1避免重复
from = Math.max(1000 / i, i + 1);
to = Math.min(10000 / i, 100);
for (int j = from; j < to; j++) {
i_val = i * j;
//判断是否存在两个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是一个吸血鬼数 ,可以假设 val = x * y,
则x和y有以下几种可能
1. x = 10a + b, y = 10c + d
2. x = 10b + a, y = c + 10d
....
针对上面假设的x和y,进行 val-x-y 操作则有一下几种结果
1.val-x-y = 990a + 99b
2.val-x-y = 999a + 90b + 9c -9d
...
由上面结果可以,吸血鬼数一定满足 val-x-y能被9整除