欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

玩转24点游戏!使用Java和DFS深入学习算法

最编程 2024-01-23 20:06:55
...

描述

题目描述

给出4个1-10的数字,通过加减乘除运算,得到数字为24就算胜利,除法指实数除法运算,本题对数字选取顺序无要求,但每个数字仅允许使用一次,且不考虑括号运算

此题允许数字重复,如3 3 4 4为合法输入,但是每个数字只允许使用一次,如此处一共有两个3,则运算过程中两个3都被选取计算一次,所以3被调用运算两次,但是对应读入的两个数字

示例

 

知识点:搜索,DFS,回溯

import java.util.Scanner;

public class Main{
    // 4个数字
    public static int[] nums = new int[4];
    // 4个数字对应的循环访问标识
    public static boolean[] visited = new boolean[4];
    // 是否有24点
    public static boolean flag = false;
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine()) {
            String[] strs = sc.nextLine().split(" ");
            for (int i = 0; i < strs.length; i++) {
                nums[i] = Integer.valueOf(strs[i]);
            }
            dfs(0, 0);
            System.out.println(flag);
        }
    }
    // 深度搜索
    public static void dfs(int numIndex, double sum) {
        // 终止条件: 数都已经参与计算完毕,则终止
        if(numIndex == 4) {
            // 若有某一组运算为24,则状态置为true
            if(sum == 24) {
                flag = true;
            }
        } else {
            numIndex++;
            /**
               *    每个数,都要互相参与运算:7/2 、7-2不等于2/7、2-7,所以每次循环都需要再次重新全部计算。
             * eg:7 2 1 10
               *   循环4个数:第一次循环用7作为主数,与其它的数做加减乘除,这时需要将访问标识为已访问,
               *   计算完,访问状态需要恢复为未访问状态。(用于下一次循环计算)
               *   第二次循环用2作为主数,与其它的数做加减乘除
             */
            for (int i = 0; i < nums.length; i++) {
                if(!visited[i]) {
                    // 标记这轮循环中这个值已经访问过
                    visited[i] = true;
                    // 递归计算,加减乘除        
                    dfs(numIndex, sum + nums[i]);
                    dfs(numIndex, sum - nums[i]);
                    dfs(numIndex, sum * nums[i]);
                    dfs(numIndex, sum / nums[i]);
                    // 恢复访问标识
                    visited[i] = false;
                }
                
            }
        }
    }
}

广度优先搜索(BFS)
  搜索步骤: 
  a .首先选择一个顶点作为起始顶点,并将其染成灰色,其余顶点为白色。 
  b. 将起始顶点放入队列中。 
  c. 从队列首部选出一个顶点,并找出所有与之邻接的顶点,将找到的邻接顶点放入队列尾部,将已访问过顶点涂成黑色,没访问过的顶点是白色。如果顶点的颜色是灰色,表示已经发现并且放入了队列,如果顶点的颜色是白色,表示还没有发现 
  d. 按照同样的方法处理队列中的下一个顶点。 
基本就是出队的顶点变成黑色,在队列里的是灰色,还没入队的是白色。 

深度优先搜索(DFS)
  深度优先遍历图的方法是,从图中某顶点v出发: 
  a.访问顶点v; 
  b.依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问; 
  c.若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 

参考链接:https://blog.****.net/yimixgg/article/details/90023121

参考链接:https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb?tpId=37&&tqId=21290&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking