TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
提前声明. 此算法来自 【老紫竹】.
老紫竹CSDN ID:java2000_net 主页http://www.laozizhu.com/
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);
}
}
[/code]
运行结果
第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
[/code] count 次数只有232.. 已经算是最高效的了.
而主要的高效代码 只有3行代码
if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {
continue;
} [/code] 而已
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整除,所以可以直接过滤其他数字。
完毕.
改成int数组,时间消耗大概只有原来的1/9
package com.kwzh;
import java.util.Arrays;
public class VampireNumber {
public static void main(String[] args) {
float f = System.nanoTime();
new VampireNumber().vampireArray();
System.out.println("string array: " + (System.nanoTime() - f)
+ " nano seconds");
f = System.nanoTime();
new VampireNumber().vampireArray2();
System.out.println("int array: " + (System.nanoTime() - f)
+ " nano seconds");
}
public void vampireArray() {
int small, big, product, floor = 10, ceil = 100;
int from, count = 0, sum = 0;
String[] ar_str1, ar_str2;
for (small = floor; small < ceil; small++) {
from = Math.max(1000 / small, small + 1);
for (big = from; big < ceil; big++) {
product = small * big;
if (product % 100 == 0 || (product - small - big) % 9 != 0) {
continue;
}
ar_str1 = String.valueOf(product).split("");
ar_str2 = (String.valueOf(small) + String.valueOf(big))
.split("");
Arrays.sort(ar_str1);
Arrays.sort(ar_str2);
if (Arrays.equals(ar_str1, ar_str2)) {
// 排序后比较,为真则找到一组
// 返回两个Objects数组彼此相等,返回true
sum++;
System.out.println("第" + sum + "组: " + small + "*" + big
+ "=" + product);
}
count++;
}
}
System.out.println(count);
}
public void vampireArray2() {
int small, big, product, floor = 10, ceil = 100;
int from, count = 0, sum = 0;
int[] ar_int1 = new int[4], ar_int2 = new int[4];
for (small = floor; small < ceil; small++) {
from = Math.max(1000 / small, small + 1);
for (big = from; big < ceil; big++) {
product = small * big;
if (product % 100 == 0 || (product - small - big) % 9 != 0) {
continue;
}
ar_int1[0] = small / 10;
ar_int1[1] = small % 10;
ar_int1[2] = big / 10;
ar_int1[3] = big % 10;
ar_int2[0] = product / 1000;
product = product % 1000;
ar_int2[1] = product / 100;
product = product % 100;
ar_int2[2] = product / 10;
ar_int2[3] = product % 10;
Arrays.sort(ar_int1);
Arrays.sort(ar_int2);
if (Arrays.equals(ar_int1, ar_int2)) {
sum++;
System.out.println("第" + sum + "组: " + small + "*" + big
+ "=" + product);
}
count++;
}
}
System.out.println(count);
}
}
[/code]
源码下载:http://file.javaxxz.com/2014/11/10/000218781.zip |
|