题解 | 24点游戏算法

24点游戏算法

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

import java.util.*;
import java.io.*;

public class Main {
    static int[] nums = new int[4];
    static int[] perm = new int[4]; // 存储当前排列
    static boolean[] visit = new boolean[4];
    static boolean found = false;
    private static final double EPSILON = 1e-6;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            found = false;
            String[] a = in.nextLine().split(" ");
            for (int i = 0; i < 4; i++) {
                nums[i] = Integer.parseInt(a[i]);
            }
            
            // 对数组排序,便于后续去重处理
            Arrays.sort(nums);
            generatePermutations(0);
            
            System.out.println(found);
        }
        in.close();
    }

    // 生成所有可能的排列(修复重复数字处理)
    static void generatePermutations(int index) {
        if (found) return;
        
        if (index == 4) {
            double x= 24;
            dfs((double)perm[0], 0, x);
            return;
        }
        
        for (int i = 0; i < 4; i++) {
            if (!visit[i]) {
                // 关键修复:仅当相同数字的前一个已被使用时,才允许使用当前数字
                // 避免重复排列,但保留有效组合
                if (i > 0 && nums[i] == nums[i-1] && !visit[i-1]) {
                    continue;
                }
                visit[i] = true;
                perm[index] = nums[i];
                generatePermutations(index + 1);
                visit[i] = false;
            }
        }
    }

    // DFS计算逻辑保持不变
    static void dfs(double last, int i, double target) {
        if (found) return;
        
        if (i == 3) {
            if (Math.abs(last - target) < EPSILON) {
                found = true;
            }
            return;
        }
        
        int next = perm[i + 1];
        
        if(i==1&&last!=0){
            dfs(perm[i + 1]+perm[i + 2], i + 2, target/last);
            if (found) return;
            dfs(perm[i + 1]-perm[i + 2], i + 2, target/last);
            if (found) return;    
        }
        
        dfs(last + next, i + 1, target);
        if (found) return;
        
        dfs(last - next, i + 1, target);
        if (found) return;
        
        dfs(next - last, i + 1, target);
        if (found) return;
        
        dfs(last * next, i + 1, target);
        if (found) return;
        
        if (Math.abs(next) > EPSILON) {
            dfs(last / next, i + 1, target);
            if (found) return;
        }
        
        if (Math.abs(last) > EPSILON) {
            dfs(next / last, i + 1, target);
            if (found) return;
        }
    }
}

写一下评论区都没完善的思路:

1 计算过程可能有小数

2 没有考虑括号优先级

3 题目数组顺序可以改变

用排列+搜索+特殊处理括号优先级

全部评论

相关推荐

头像
10-27 15:50
门头沟学院 Java
想进开水团喝开水:有一种店 只能外卖 不能堂食 你猜为什么
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务