吸血鬼数是指位数为偶数的数字,可以由一 对数字相乘而得到,而这对数字各包含乘积的一半 位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是 “吸血鬼”数字:
1260=21 * 60
1827=21 * 87
2187= 27 * 81
那么,开始
由于判断四位数是否能分解为两个两位数的乘积,比判断两位数的乘积所得四位数的,要麻烦得多,因此思路为后者。
import java.util.ArrayList; import java.util.Arrays; /** * 先从1001开始到9999开始判断,是否能分解为两个二位数,如果可以,二维数是否包含所有四个数字 * 把四位数分解成二位数乘积过于麻烦,而且一个四位数可能存在多种分解方式,加大了设计的难度 * 但是反过来,二位数乘以二位数简单得多,此时再去判断即可 * 将积分解成四个数位,存入数组。两个乘数分别分解成两个数位,存入一个数组 * 将两个数组排序,按照下标逐个比较,如果两个数组相同,返回true * @author zhaoke * */ public class Vampire { //冒泡排序法 public void sort(int[] array) { for (int i = 0; i < array.length-1; i++) { for (int j = i+1; j < array.length; j++) { if (array[i] > array[j]) { //交换两个数的位置 array[i] = array[i] - array[j]; array[j] = array[i] + array[j]; array[i] = array[j] - array[i]; } } } } /** * 判断四位数分解后的数位(存在数组里),是否恰好包含两个乘积因子的所有数位 * 为了简单起见,方法是先排序,然后比较两个数组是否相同 */ public boolean check(int[] digits, int num1, int num2) { this.sort(digits); // System.out.println(Arrays.toString(digits)); int[] factors = new int[4]; //分离第一个乘数的两个数位 int[] numArray = this.divideNumber(num1); for (int i = 0; i < 2; i++) { factors[i] = numArray[i]; } //分离第二个乘数的两个数位 numArray = this.divideNumber(num2); for (int i = 2; i < 4; i++) { factors[i] = numArray[i-2]; } this.sort(factors); // System.out.println(Arrays.toString(factors)); for (int i = 0; i < digits.length; i++) { if (digits[i] != factors[i]) { return false; } } return true; } public int[] divideNumber(int number) { int[] digits = new int[2]; digits[0] = number/10; digits[1] = number - 10*(number/10); return digits; } /** * 获得每个位的数字 */ public int[] divideArray(int number) { int[] digits = new int[4]; int factor = 1000; for (int i = 0; i < digits.length; i++) { digits[i] = number/factor; number -= digits[i] * factor; factor /= 10; } return digits; } ArrayList<Integer> result = new ArrayList<Integer>(); /** * 10*99小于1000,因此从11开始循环 */ public void start() { int count = 0; //计数器而已 for (int i = 11; i < 100; i++) { for (int j = 11; j < 100; j++) { if (i*j <1000) continue; if (i*j%100==0) { //根据题目,如果最后两位是0,也不可 continue; } int[] digits = divideArray(i*j); if (this.check(digits, i, j)) { if (this.result.contains(i*j)) continue; this.result.add(i*j); System.out.printf("第%d个吸血鬼数: %d = %d x %d ",++count,i*j,i,j); } } } } public static void main(String[] args) { Vampire v = new Vampire(); v.start(); } }
结果如下:
第1个吸血鬼数: 1395 = 15 x 93 第2个吸血鬼数: 1260 = 21 x 60 第3个吸血鬼数: 1827 = 21 x 87 第4个吸血鬼数: 2187 = 27 x 81 第5个吸血鬼数: 1530 = 30 x 51 第6个吸血鬼数: 1435 = 35 x 41 第7个吸血鬼数: 6880 = 80 x 86
总结:逆向思维,模块化设计