吸血鬼数字 高效算法
提前声明. 此算法来自 【老紫竹】.
老紫竹CSDN ID:java2000_net
废话不多说.直接上代码
- package com.javaeye.arrick.util;
- import java.util.Arrays;
- /**
- * 吸血鬼数字,高效率版本.<br>
- * 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。<br>
- * 比如 1395 =15 * 93
- *
- * @author 老紫竹(laozizhu.com)
- */
- public class VampireNumber {
- 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); //返回两个int值中较大的一个
- to = Math.min(10000 / i, 100); //返回两个int值中较小的一个
- for (int j = from; j < to; j++) {
- i_val = i * j;
- 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)) {
- // 排序后比较,为真则找到一组
- // 返回两个Objects数组彼此相等,返回true
- sum++;
- System.out.println("第" + sum + "组: " + i + "*" + j + "=" + i_val);
- }
- }
- }
- System.out.println("共找到" + sum + "组吸血鬼数");
- System.out.println(count);
- }
- }
运行结果
- 第1组: 15*93=1395
- 第2组: 21*60=1260
- 第3组: 21*87=1827
- 第4组: 27*81=2187
- 第5组: 30*51=1530
- 第6组: 35*41=1435
- 第7组: 80*86=6880
- 共找到7组吸血鬼数
- 232
count 次数只有232.. 已经算是最高效的了.
而主要的高效代码 只有3行代码
- if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {
- continue;
- }
而已
i_val % 100 -->都明白什么意思.
(i_val - i -j) % 9 !=0 --> 也许一时想不明白.
请看如下逻辑. 你会一目了然
算法解释:
假设
i_val = 1000a + 100b + 10c + d,
因为满足i_val = x * y,
则有x = 10a + b, y = 10c + d
则i_val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c)
所以i_val - x - y能被9整除。
所以满足该条件的数字必定能被9整除,所以可以直接过滤其他数字。
完毕.
《Thinking in Java》 (Dan Forhan推荐练习代码)
浙公网安备 33010602011771号