• LeetCode 679 24点游戏


    题目链接:LeetCode 679 24点游戏

    题目大意:
    给定四个数,判断是否可以通过加减乘除和括号计算出\(24\)点。

    题解:
    一共有\(4\)个数和\(3\)个运算操作,因此可能性非常有限。
    首先从\(4\)个数字中有序地选出\(2\)个数字,共有\(4 \times 3 = 12\)种选法,并选择加、减、乘、除\(4\)种运算操作之一,用得到的结果取代选出的\(2\)个数字,剩下\(3\)个数字。
    然后在剩下的\(3\)个数字中有序地选出\(2\)个数字,共有\(3 \times 2 = 6\)种选法,并选择\(4\)种运算操作之一,用得到的结果取代选出的\(2\)个数字,剩下\(2\)个数字。
    最后剩下\(2\)个数字,有\(2\)种不同的顺序,并选择\(4\)种运算操作之一。
    因此,一共有\(12 \times 4 \times 6 \times 4 \times 2 \times 4 = 9216\)种不同的可能性。
    通过搜索和回溯遍历所有的可能情况。

    class Solution {
    public:
        static constexpr int TARGET = 24;
        static constexpr double EPSILON = 1e-6;
        static constexpr int ADD = 0, MULTIPLY = 1, SUBTRACT = 2, DIVIDE = 3;
    
        bool judgePoint24(vector<int>& cards) {
            vector<double> list;
            for (const int& num : cards) {
                list.emplace_back(static_cast<double>(num));
            }
            return solve(list);
        }
    
        bool solve(vector<double>& list) {
            if (list.size() == 1) {
                return fabs(list[0] - TARGET) < EPSILON;
            }
            int size = list.size();
            for (int i = 0; i < size; ++i) {
                for (int j = 0; j < size; ++j) {
                    if (i != j) {
                        vector<double> list2;
                        for (int k = 0; k < size; ++k) {
                            if (k != i && k != j) {
                                list2.emplace_back(list[k]);
                            }
                        }
                        for (int k = 0; k < 4; ++k) {
                            if (k < 2 && i > j) { // 加法和乘法交换律
                                continue;
                            }
                            if (k == ADD) { // 加
                                list2.emplace_back(list[i] + list[j]);
                            } else if (k == MULTIPLY) { // 减
                                list2.emplace_back(list[i] * list[j]);
                            } else if (k == SUBTRACT) { // 乘
                                list2.emplace_back(list[i] - list[j]);
                            } else if (k == DIVIDE) { // 除
                                if (fabs(list[j]) < EPSILON) { 
                                    continue;
                                }
                                list2.emplace_back(list[i] / list[j]);
                            }
                            if (solve(list2)) {
                                return true;
                            }
                            list2.pop_back();
                        }
                    }
                }
            }
            return false;
        }
    };
    
  • 相关阅读:
    DOS命令备忘
    JS面向对象总结
    java 内部类如何访问外部类的对象
    java注解的学习
    VisualVM远程连接服务器设置方法
    oracle 多表插入
    jvm对类的加载顺序测试
    oracle性能学习中总结
    java 权限修饰符的总结
    oracle多单号的说明
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15861975.html
Copyright © 2020-2023  润新知