1.16 24点游戏

1.16 24点游戏

基本问题 你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24。

解法

  • 解法1:暴力
  • 解法2:记忆化+二进制 (这个个人能力有限,写不出来)

拓展问题

1 测试几个用例

easy

2 不妨考虑一下,如果要优化上述算法,可以从那几个方面入手?

存在重复的计算,采用记忆化的方法进行优化

3 若给你n张牌,要求最后的结果是m,又该如何解答呢?

一样,只不过是在slove方法里面循环变多而已

4 如果阶乘!也是一种运算符号,那么又如何解答呢?

就在solve方法遍历符号的时候多加一个运算符号就可以了

All Coding

// 1.16 24点游戏
import java.util.*;
class Test{
	static final int TARGET = 24;
    static final double EPSILON = 1e-6;
    static final int ADD = 0, MULTIPLY = 1, SUBTRACT = 2, DIVIDE = 3;
	public static void main(String[] args) {
		/**
		基本问题:你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24。
		> 解法
			解法1:暴力
			解法2:记忆化+二进制 (这个个人能力有限,写不出来)
		*/
		int[] nums = new int[]{4, 1, 8, 7};
		System.out.println(judgePoint24(nums));
	}
	public static boolean judgePoint24(int[] nums) {
        List<Double> list = new ArrayList<Double>();
        for (int num : nums) list.add((double) num);
        return solve(list);
    }
	public static boolean solve(List<Double> list) {
        if (list.size() == 0) return false;
        if (list.size() == 1) return Math.abs(list.get(0) - TARGET) < EPSILON;
        int size = list.size();
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (i != j) {
                    List<Double> list2 = new ArrayList<Double>();
                    for (int k = 0; k < size; k++) if (k != i && k != j) list2.add(list.get(k));
                    for (int k = 0; k < 4; k++) {
                        if (k < 2 && i > j) continue;
                        if (k == ADD) {
                            list2.add(list.get(i) + list.get(j));
                        } else if (k == MULTIPLY) {
                            list2.add(list.get(i) * list.get(j));
                        } else if (k == SUBTRACT) {
                            list2.add(list.get(i) - list.get(j));
                        } else if (k == DIVIDE) {
                            if (Math.abs(list.get(j)) < EPSILON) {
                                continue;
                            } else {
                                list2.add(list.get(i) / list.get(j));
                            }
                        }
                        if (solve(list2)) {
                            return true;
                        }
                        list2.remove(list2.size() - 1);
                    }
                }
            }
        }
        return false;
    }
    /**
    拓展问题:
    1 测试几个用例
    	easy
    2 不妨考虑一下,如果要优化上述算法,可以从那几个方面入手?
    	存在重复的计算,采用记忆化的方法进行优化
    3 若给你n张牌,要求最后的结果是m,又该如何解答呢?
    	一样,只不过是在slove方法里面循环变多而已
    4 如果阶乘!也是一种运算符号,那么又如何解答呢?
    	就在solve方法遍历符号的时候多加一个运算符号就可以了

    */

}
posted @ 2020-12-02 21:01  BOTAK  阅读(85)  评论(0)    收藏  举报