吸血鬼数的查找算法

《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整除



原文地址:https://www.cnblogs.com/jeasion/p/10758348.html