2017 9数算式

观察如下的算式:


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值