全数字的乘积

如果一个n位数包含了1至n的所有数字恰好一次,我们称它为全数字的;例如,五位数15234就是1至5全数字的。

7254是一个特殊的乘积,因为在等式39 × 186 = 7254中,被乘数、乘数和乘积恰好是1至9全数字的。

找出所有被乘数、乘数和乘积恰好是1至9全数字的乘法等式,并求出这些等式中乘积的和。

注意:有些乘积可能从多个乘法等式中得到,但在求和的时候只计算一次。

package EULER32;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/11/10.
 * 思路:如果是1-9全数字只能:一位数*四位数=四位数,二位数*三位数=四位数
 * 根据乘积位数的限制,确定两个乘数的首位,在剩下的七个数里排序7*6*5种可能确定两个乘数,求出乘积判断是否为全数字
 * 桶排去重的话要1w次,用map的话满足条件的应该比100个少,map快一点
 * 其他时间复杂度较高但代码简单思路:列出1-9全部排列为9!按144判断一遍是否符合,按234判断一遍是否组合
 */
public class EULER32 {
    private static long start = System.currentTimeMillis();
    private static List<String> numList = new ArrayList<String>();
    static {
        numList.add(String.valueOf(1));
        numList.add(String.valueOf(2));
        numList.add(String.valueOf(3));
        numList.add(String.valueOf(4));
        numList.add(String.valueOf(5));
        numList.add(String.valueOf(6));
        numList.add(String.valueOf(7));
        numList.add(String.valueOf(8));
        numList.add(String.valueOf(9));
    }
    public static void main(String[] args){
        Map<Integer,Integer> map = new HashMap<Integer, Integer>();
        int multiplier = 0;
        int product = 0;
        //一位数乘四位数
        for(int i=1;i<10;i++){//一位数i
            numList.remove(String.valueOf(i));
            for (int j=10/i;j>0;j--){//j为四位数的千位,当j>10/i,时,乘积为五位数,等于10/i也可能为五位数,在判断是否全数的逻辑控制
                if (i == j || j > 9)
                    continue;
                numList.remove(String.valueOf(j));
                for (int a=0;a<numList.size();a++){
                    int hundred = Integer.valueOf(numList.get(a));
                    numList.remove(a);
                    for (int b=0;b<numList.size();b++){
                        int ten = Integer.valueOf(numList.get(b));
                        numList.remove(b);
                        for (int c=0;c<numList.size();c++){
                            int one = Integer.valueOf(numList.get(c));
                            multiplier = j*1000+hundred*100+ten*10+one;
                            product = i*multiplier;
                            if (isPandigital(product,i,j,one,ten,hundred)){
                                map.put(product,1);
                                System.out.println(i + "*" + multiplier+"="+product);
                            }
                        }
                        numList.add(b,String.valueOf(ten));
                    }
                    numList.add(a,String.valueOf(hundred));
                }
                numList.add(String.valueOf(j));
            }
            numList.add(String.valueOf(i));
        }
        //二位数乘三位数
        for(int i=1;i<10;i++){//两位数的十位数i
            numList.remove(String.valueOf(i));
            for (int j=10/i;j>0;j--){//j为三位数的百位,当j>10/i,时,乘积不可能为四位数
                if (i == j || j > 9)
                    continue;
                numList.remove(String.valueOf(j));
                for (int a=0;a<numList.size();a++){
                    int one_i = Integer.valueOf(numList.get(a));
                    numList.remove(a);
                    for (int b=0;b<numList.size();b++){
                        int ten = Integer.valueOf(numList.get(b));
                        numList.remove(b);
                        for (int c=0;c<numList.size();c++){
                            int one = Integer.valueOf(numList.get(c));
                            multiplier = j*100+ten*10+one;
                            product = (i*10+one_i)*multiplier;
                            if (isPandigital(product,i,j,one,ten,one_i)){
                                map.put(product,1);
                                System.out.println(i*10+one_i + "*" + multiplier+"="+product);
                            }
                        }
                        numList.add(b,String.valueOf(ten));
                    }
                    numList.add(a,String.valueOf(one_i));
                }
                numList.add(String.valueOf(j));
            }
            numList.add(String.valueOf(i));
        }
        int totle = 0;
        for (Integer i:map.keySet()){
            totle += i;
        }
        System.out.println(totle);
        long end = System.currentTimeMillis();
        System.out.print("总用时:"+(end-start)+"毫秒");
    }

    public static boolean isPandigital(int num, int... var){
        if (num < 1000 || num > 9999)//乘积不是四位数
            return false;
        List<Integer> bitList = new ArrayList<Integer>();
        while (num > 0) {
            int bit = num%10;
            if (bit == 0)
                return false;
            for (int i = 0; i < bitList.size(); i++){
                if (bitList.get(i) == bit)
                    return false;
            }
            bitList.add(bit);
            for (int i = 0; i < var.length; i++) {
                if (var[i] == bit)
                    return false;
            }
            num /= 10;
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值