观察如下的算式:
9213 x 85674 = 789314562
左边的乘数和被乘数正好用到了1~9的所有数字,每个1次。
而乘积恰好也是用到了1~9的所有数字,并且每个1次。
请你借助计算机的强大计算能力,找出满足如上要求的9数算式一共有多少个?
注意:
1. 总数目包含题目给出的那个示例。
9213 x 85674 = 789314562
左边的乘数和被乘数正好用到了1~9的所有数字,每个1次。
而乘积恰好也是用到了1~9的所有数字,并且每个1次。
请你借助计算机的强大计算能力,找出满足如上要求的9数算式一共有多少个?
注意:
1. 总数目包含题目给出的那个示例。
2. 乘数和被乘数交换后作为同一方案来看待。
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
System.out.println(Calculator.calculate());
}
public static class Calculator {
/**
* a + b = 9 && c = 9; 乘数位数+被乘数位数=9且乘积位数为9,分层有:
* a = 1 && b = 8;a = 2 && b = 7;a = 3 && b = 6;a = 4 && b = 5;
* @return
*/
public static int calculate() {
int a = 0;
int b = 0;
int sum = 0;
Set<Integer> set = new HashSet<Integer>();
//人工分层减少计算量
for (a = 1; a <= 10; a++) { //a=1 && b=8
for (b = 10000000; b <=100000000; b++) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 10; a <= 100; a++) { //a=2 && b=7
for (b = 1000000; b <=10000000; b++) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 100; a <= 1000; a++) { //a=3 && b=6
for (b = 100000; b <=1000000; b++) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 1000; a <= 10000; a++) { //a=4 && b=5
for (b = 10000; b <=100000; b++) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
return sum;
}
public static boolean checkNum(int a, int b, int c) {
Set<Integer> set = new HashSet<Integer>();
Set<Integer> set1 = new HashSet<Integer>();
int val = a;
while (val >= 10) {
if (set.contains(val % 10)) {
return false;
}
set.add(val % 10);
val /= 10;
}
if (set.contains(val)) {
return false;
}
set.add(val);
val = b;
while (val >= 10) {
if (set.contains(val % 10)) {
return false;
}
set.add(val % 10);
val /= 10;
}
if (set.contains(val)) {
return false;
}
set.add(val);
val = c;
while(val >=10){
if(set1.contains(val % 10)) {
return false;
}
set1.add(val % 10);
val/=10;
}
if(set1.contains(val)){
return false;
}
set1.add(val);
return set.size() == 9 //等号左边数字1-9均出现
&& set.contains(1) && set.contains(2)&& set.contains(3)
&& set.contains(4) && set.contains(5)&& set.contains(6)
&& set.contains(7) && set.contains(8)&& set.contains(9)
&& set1.size() == 9 //等号右边数字1-9均出现
&& set1.contains(1) && set1.contains(2)&& set1.contains(3)
&& set1.contains(4) && set1.contains(5)&& set1.contains(6)
&& set1.contains(7) && set1.contains(8)&& set1.contains(9);
}
}
}
运行结果:
看到输出结果,无意中发现规律,即乘数,被乘数,乘积皆为3的倍数
于是根据此规律,在前期预处理时算法可进一步简化,减少运算量
将人工分层处改之
//人工分层减少计算量
for (a = 3; a <= 9; a=a+3) { //a=1 && b=8
for (b = 10000002; b <=99999999; b=b+3) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 12; a <= 99; a=a+3) { //a=2 && b=7
for (b = 1000002; b <=9999999; b=b+3) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 102; a <= 999; a=a+3) { //a=3 && b=6
for (b = 100002; b <=999999; b=b+3) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
for (a = 1002; a <= 9999; a=a+3) { //a=4 && b=5
for (b = 10002; b <=99999; b=b+3) {
if (checkNum(a, b, a * b)) {
System.out.println(a + "*" + b + "=" + a * b);
set.add(a * b);
sum++;
}
}
}
总结:此题是project euler 第32题的变形题
推荐链接:http://www.worldofnumbers.com/ninedig1.htm
http://blog.csdn.net/zhangzhengyi03539/article/details/47061087