吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是“吸血鬼”数字:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
1994年柯利弗德·皮寇弗在Usenet社群sci.math的文章中首度提出吸血鬼数。后来皮寇弗将吸血鬼数写入他的书Keys to Infinity的第30章。
最初几个吸血鬼数为:
1260, 1395, 1435, 1530, 1827, 2187, 6880, 102510, 104260, 105210, 105264, 105750, 108135, 110758, 115672, 116725, 117067, 118440, 120600, 123354, 124483, 125248, 125433, 125460, 125500, ...
import java.util.Arrays; public class Vampire { public static boolean isVamp1(long i, long j) { // 方法1 long n = i * j; int[] digits = new int[10]; while (n > 0) { digits[(int) n % 10]++; n = n / 10; } while (i > 0) { digits[(int) i % 10]--; i = i / 10; } while (j > 0) { digits[(int) j % 10]--; j = j / 10; } for (int k = 0; k < 10; k++) { if (digits[k] > 0) return false; } return true; } public static boolean isVamp2(long i, long j) { // 方法2 String[] str1, str2; long n = i * j; str1 = String.valueOf(n).split(""); str2 = (String.valueOf(i) + String.valueOf(j)).split(""); Arrays.sort(str1); Arrays.sort(str2); // 对字符串进行排序 if (Arrays.equals(str1, str2)) // 排序后比较 return true; else return false; } public static void main(String[] args) { int count1 = 0, count2 = 0; int n = 6, n1 = n / 2; // n为积位数,需为偶数,n1为乘数位数 long a = (long) Math.pow(10, n1 - 1); // 乘数下限,这里为100 long b = (long) Math.pow(10, n1); // 乘数上限,这里为1000 long c = (long) Math.pow(10, n - 1); // 积下限,这里为100000 long e = (long) Math.pow(10, n); // 积上限,这里为1000000 long from, to; for (long i = a; i < b; i++) { from = Math.max(c / i, i + 1); to = Math.min(e / i, b); for (long j = from; j < to; j++) { long d = i * j; if (d % 100 == 0 || (d - i - j) % 9 != 0) { continue; } if ((d > c) && isVamp1(i, j)) { count1++; System.out.println("方法1第" + count1 + "组" + i + "*" + j + "=" + d); } if ((d > c) && isVamp2(i, j)) { count2++; System.out.println("方法2第" + count2 + "组:" + i + "*" + j + "=" + d); } } } System.out.println("方法1共找到:" + count1 + "组吸血鬼数"); System.out.println("方法2共找到:" + count2 + "组吸血鬼数"); } }