【c++】【leetcode679】24点游戏(暴力枚举dfs+代码优化)

leetcode 679: 24点游戏
在这里插入图片描述

解题思路

1、整数转换为浮点数求解,因为除法可能会出现小数
2、浮点数和24比较,确定一个精度误差
3、枚举所有的可能,如果达到24进行剪枝

核心

  • 在4个数中任选两个数进行四则运算,假设为a op b = x,此时在数组中删除ab,把x加入数组中,在剩下的三个数里任选两个进行四则运算。
  • 当数组中只剩下一个数时,说明运算完成,与24比较即可。

代码

class Solution {
public:
    const double eps = 1e-8;
    double f(double a,double b,int op){
        switch(op){
            case 0:return a + b;
            case 1:return a - b;
            case 2:return a * b;
            case 3:return a / b;
        }
        return -1;
    }
    bool dfs(vector<double> v){
        int n = v.size();
        if(n == 1) return abs(v.back() - 24) < eps;//浮点数和整数比较需要考虑精度问题
        for(int i = 0;i < n;++i)
            for(int j = 0;j < n;++j) if(i != j){//选的数不能一样
                //随机选两个数
                    for(int k = 0;k < 4;k++){
                        double ans = f(v[i],v[j],k);//返回两个数运算的结果,k代表操作运算
                        //保留运算结果,删除选中的两个数
                        vector<double> tmp;
                        tmp.emplace_back(ans);
                        //删除选中的两个数
                        for(int l = 0;l < n;++l){
                            if(l != i && l != j)tmp.emplace_back(v[l]);
                        }
                        if (dfs(tmp))return true;//如果已经得到24就剪枝
                    }
                }  
        return false;
    }
    bool judgePoint24(vector<int>& cards) {
        vector<double> v;
        for(auto x : cards)v.emplace_back(x);//都转换为浮点数运算
        return dfs(v);
    }
};
//枚举所有的可能

代码优化

  • 如果除数为0进行剪枝
  • + *具备交换律,可以减少运算量
class Solution {
public:
    const double eps = 1e-6;
    bool dfs(vector<double> v){
        int n = v.size();
        if(n == 1) return abs(v.back() - 24) < eps;//浮点数和整数比较考虑精度问题
        for(int i = 0;i < n;++i)
            for(int j = 0;j < n;++j) if(i != j){//选的数不能一样
                //随机选两个数,删除这两个数
                vector<double> tmp;
                for(int l = 0;l < n;++l){
                    if(l != i && l != j)tmp.emplace_back(v[l]);
                }
                double a = v[i],b = v[j];
                for(int k = 0;k < 4;++k){
                    if(k < 2 && i > j)continue;
                    if(k == 0)tmp.emplace_back(a + b);
                    else if (k == 1)tmp.emplace_back(a * b);
                    else if(k == 2)tmp.emplace_back(a - b);
                    else if(k == 3) {
                        if(fabs(b) < eps)continue;
                        else tmp.emplace_back(a / b);
                    }
                    if(dfs(tmp))return true;
                    tmp.pop_back();
                }
            }  
        return false;
    }
    bool judgePoint24(vector<int>& cards) {
        vector<double> v;
        for(auto x : cards) v.emplace_back(x);//都转换为浮点数运算
        return dfs(v);
    }
};
//枚举所有的可能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值