吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个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 + "组吸血鬼数");
}
}