九数算式——深度优先搜索

空扰寡人 提交于 2020-03-03 01:00:58

/*标题:9数算式

观察如下的算式:
9213 x 85674 = 789314562
左边的乘数和被乘数正好用到了1~9的所有数字,每个1次。
而乘积恰好也是用到了1~9的所有数字,并且每个1次。
请你借助计算机的强大计算能力,找出满足如上要求的9数算式一共有多少个?

注意:

  1. 总数目包含题目给出的那个示例。
  2. 乘数和被乘数交换后作为同一方案来看待。
    答案:1625
    解题思路:
    首先对九个数进行全排列,用到深度优先搜索(dfs),判断递归出口的条件;
    其次对每种排列分割成两数相乘,利用数组循环;
    最后判断结果是否满足题目的条件:用到了1~9的所有数字,满足则计数加一
public class NineNumber {
    //先定义1~9的字符数组
    static char[] num = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9'};
    //定义一个 访问数组,表示该元素是否被用过
    static boolean[] vis = new boolean[9];
    //计数排列的个数
    static int count = 0;
    //排列以字符串的形式输出
    static String str = "";

    //访问数组元素初始化
    public static void init(int i) {
        vis[i] = false;
    }

    public static void main(String[] args) {
        dfs(0, str);
        System.out.println("共有" + count / 2 + "种排列");//乘数和被乘数交换后作为同一方案来看待
    }

    //深度优先搜索
    static void dfs(int n, String str) {//将乘数被乘数1-9进行排列
        //边界条件,达到边界就输出排列的字符串
        if (n == 9) {
            split(str);
            //System.out.println(str);
            return;
        }
        for (int i = 0; i < 9; i++) {
            if (vis[i] == false) {
                vis[i] = true;//标记被访问
                dfs(n + 1, str + num[i]);
                init(i);//访问数组初始化
            }
        }
    }

    //将排序的数分成两个数相乘
    public static void split(String str) {
        for (int i = 0; i < 8; i++) {
            String str1 = str.substring(0, i + 1);
            String str2 = str.substring(i + 1, 9);
            //将子字符串转为int整数
            int a = Integer.parseInt(str1);//被乘数
            int b = Integer.parseInt(str2);//乘数
            int result = a * b;
            //检验结果是否满足题目要求
            if (check(result)) {
                System.out.println(a + "*" + b + "=" + result);//输出结果,便于检查
                count++;
            }
        }
    }

    //检验方法,要求结果满足是1~9所有数,且不重复
    public static boolean check(int res) {
        String str = String.valueOf(res);//将参数转换为字符串
        boolean[] vis = new boolean[10];//标记使用的数组
        vis[0] = true;//因为字符串中没有0,所以把它设置为访问过
        if (str.length() != 9) {
            return false;
        }
        for (int i = 0; i < 9; i++) {
            int n = Integer.parseInt(str.substring(i, i + 1));
            if (vis[n] == false) {//判断是否重复
                vis[n] = true;//标记被访问过
            } else {
                return false;
            }
        }
        return true;
    }

}

运行结果:
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!