吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是“吸血鬼”数字:
1260 = 21 X 60 1827 = 21 X 87 2187 = 27 X 81
4位数的吸血鬼数有7个:
1260, 1395, 1435, 1530, 1827, 2187, 6880
这本是《java编程思想》里的一道编程题,本来只是用来让大家练习java的分支与循环。当时感觉应该是有巧妙解法的,在网上找到了如下解法。
import java.util.Arrays;
public class Demmo
{
public static void main(String[] arg)
{
String[] targetNum;
String[] judgeNum;
int from,to;
int c=0;
long startTime=System.currentTimeMillis();
for(int i=10;i<100;i++)
{
from=Math.max(1000/i,i+1);
to=Math.min(10000/i,100);
for (int j = from; j <to; j++)
{
int n = i * j;
if((n-i-j)%9!=0||n%100==0)
continue;
/*
假设val = 1000a + 100b + 10c + d, 因为满足val = x * y, 则有x = 10a + b, y = 10c + d
则val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c), 所以val - x - y能被9整除。
*/
else
{
targetNum = String.valueOf(n).split("");
judgeNum = (String.valueOf(i) + String.valueOf(j)).split("");
Arrays.sort(targetNum);
Arrays.sort(judgeNum);
if (Arrays.equals(targetNum,judgeNum)) {
c++;
System.out.print(c+":");
System.out.println(n + "=" + i + "*" + j);
}
}
}
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime+"ms");
}
}
先是将问题转化为两个二位数相乘得出四位数,再利用若n为吸血鬼数,则(n-i-j)%9 == 0,注释已给出证明,来过滤很大部分的数据。然后再将n,i,j以字符串形式拆开成字符数组,排序后比较数组是否相等,相等即为吸血鬼数字。