题解 | #24点游戏算法#

24点游戏算法

https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb

注意坑!

这题注意一下有括号对运算优先级的影响,我看之前就已经有大佬发现,排行里的部分提交代码是通过不了(9 5 7 1)的,但实际9-5=4,7-1=6,4*6 = 24。这是可以组成24的,所以一般的dfs是有bug的。

解题思路:

我就是直接模拟人工计算的方式,穷举暴力破解,我觉得是最容易理解的方式吧。人工计算方式如下:

1、从给的数字列表中随机拿两个数字
2、用这两个数字进行四则运算,算完之后放回去。
3、再重新从列表中拿两个数字
4、当列表中的数字只有一个的时候,判断一下是不是24,是则返回true
5、回溯,重新从第1步开始,选择两个其它数字,重复上述步骤

直接用代码实现上面的思路就解决问题了。各位可以想想有什么好的方式或优化。

我是没有考虑什么优化,只是觉得思路很简单清晰。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String[] a = in.nextLine().split(" ");
            ArrayList<Double> nums = new ArrayList<>();
            for (int i = 0; i < 4; i ++)
                nums.add(Double.parseDouble(a[i]));
		  //上面是处理输入,下面开始求解
            System.out.println( dfs(nums) );
        }
    }
  
    public static boolean dfs(List<Double> nums ) {
        int len = nums.size();
        //递归结束条件:当元素只有一个的时候,且值为24,则为true,否则下面返回false
        if (len == 1 && nums.get(0) == 24) {
            return true;
        }

        if (len > 1) {
            for (int i = 0; i < len ; i++) {
                for (int j = 0; j < len; j++) {
                    if ( i != j) {
                        //i表示取的第一个数索引,j表示取的第二个数索引,
                        ArrayList<Double> temp = new ArrayList<>(nums);
                        double a = temp.get(i);
                        double b = temp.get(j);
					  //把列表中的这两个数拿掉,再把加减乘除的结果放进去,递归调用自己重复这个过程
                        temp.remove((Object)a);
                        temp.remove((Object)b);
					  //+
                        temp.add(a + b);
                        if (dfs(temp)) {
                            return true;
                        }
					  //*
                        temp.add(a * b);
                        if (dfs(temp)) {
                            return true;
                        }
					  //-
                        temp.add(a - b);
                        if (dfs(temp)) {
                            return true;
                        }
					  // /
                        if (b != 0) {
                            temp.add(a / b);
                            if (dfs(temp)) {
                                return true;
                            }
                        }
                    }

                }
            }

        }
        nums.remove(len - 1);//注意一下,如果结果不对,是要回溯的,把这个放进来的值拿掉
        return false;
    }
}

#华为2023秋招求职进度交流#
全部评论

相关推荐

尊嘟假嘟点击就送:加v细说,问题很大
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务