zoukankan      html  css  js  c++  java
  • [LeetCode 679.] 24点游戏

    LeetCode 679. 24点游戏

    看到一道回溯的题目,一时有点毛爪,看leetcode的讨论,竟然发现 打表暴力枚举 的做法。受此启发写下了这份答案。

    题目描述

    You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through *, /, +, -, (, ) to get the value of 24.

    Example 1:

    Input: [4, 1, 8, 7]
    Output: True
    Explanation: (8-4) * (7-1) = 24

    Example 2:

    Input: [1, 2, 1, 2]
    Output: False

    Note:

    1. The division operator / represents real division, not integer division. For example, 4 / (1 - 2/3) = 12.
    2. Every operation done is between two numbers. In particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the expression -1 - 1 - 1 - 1 is not allowed.
    3. You cannot concatenate numbers together. For example, if the input is [1, 2, 1, 2], we cannot write this as 12 + 12.

    解题思路

    可以采取的方法:

    1. 打表
    2. 暴力枚举
    3. 回溯

    参考代码

    这里用的暴力枚举的做法:

    • 每次得到一个中间结果就把它和剩下的数字放到一起一视同仁,然后以任意顺序交换计算,用于代替加括号;
    • 使用 next_permutation 来组织数字的任意计算顺序。
    /*
     * @lc app=leetcode id=679 lang=cpp
     *
     * [679] 24 Game
     */
    
    // @lc code=start
    double add(double a, double b) { return a+b; }
    double mul(double a, double b) { return a*b; }
    double sub1(double a, double b) { return a-b; }
    double sub2(double a, double b) { return b-a; }
    double div1(double a, double b) { return a/b; }
    double div2(double a, double b) { return b/a; }
    using Func = double(*)(double, double);
    const vector<Func> calls { add, sub1, sub2, mul, div1, div2 };
    vector<double> num4;
    vector<double> num3;
    vector<double> num2;
    constexpr double eps = 1E-3;
    
    class Solution {
    public:
        bool judgePoint24(vector<int>& nums) {
            num4.clear(); // 全局变量注意重置
            for (int x : nums) num4.push_back(x);
            return judge4();
        }
        bool judge4() {
            sort(num4.begin(), num4.end());
            do {
                for (auto&& f : calls) {
                    double t1 = f(num4[0], num4[1]);
                    num3 = {t1, num4[2], num4[3]};
                    if (judge3()) return true;
                }
            } while (next_permutation(num4.begin(), num4.end()));
            return false;
        }
        bool judge3() {
            sort(num3.begin(), num3.end());
            do {
                for (auto&& f : calls) {
                    double t2 = f(num3[0], num3[1]);
                    num2 = {t2, num3[2]};
                    if (judge2()) return true;
                }
            } while (next_permutation(num3.begin(), num3.end()));
            return false;
        }
        bool judge2() {
            for (auto&& f : calls) {
                double t3 = f(num2[0], num2[1]);
                if (fabs(t3 - 24.0) < eps) return true;
            }
            return false;
        }
    };
    // @lc code=end
    
  • 相关阅读:
    mfc给对话框添加背景
    科学计数法中的尾数、基、指数
    格式化输出符号详细说明(待补充)
    写入注册表
    C++ 注册表操作
    Run-Time Check Failure #3
    完美二叉树, 完全二叉树和完满二叉树学习
    GetModuleFileNameW
    [BJDCTF2020]ZJCTF,不过如此
    picoctf_2018_buffer overflow 1/2
  • 原文地址:https://www.cnblogs.com/zhcpku/p/14508061.html
Copyright © 2011-2022 走看看