1224 红魔馆的纸牌游戏 (计算24点,dfs)

Description

红魔馆的蕾米莉亚大小姐一天发现人类有一种叫做24点的游戏,于是就带着一副不知哪里弄来的扑克牌到图书馆找帕秋莉玩 

24点游戏的规则:从一副牌中随机抽取4张牌,牌的点数为1到13之间的13个整数,要求只用加减乘除运算符以及括号,使得最终运算结果为24,每张牌的点数必须且仅能使用一次(牌的位置可任意调换) 

一副牌抽出7 8 3 1这四张扑克时,大小姐才刚想出(7-3-1)*8=24的方法,而帕秋莉却早就说出了3/(1-7/8)=24的方法,作为红魔馆威严满满的一馆之主岂能就此认输,为了大小姐能稍微捡起一点威严,现在请你帮忙,你的任务是针对每一组随机产生的四张牌,判断是否有解。 

Input

输入数据第一行是一个整数T。下面由T组测试数据组成,每组测试数据占一行,每行有4个整数a(1 <= a <= 13)代表4张牌

Output

对于每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。

Sample Input

3
6 4 3 8
8 1 7 1
3 3 7 7

Sample Output

Yes
No
Yes

题意 :

  • 计算24点

思路 和代码:

  • 递归处理,深度优先搜索

    dfs(int n) 表示我现在还剩下多少个数,没有处理

    由于有括号的原因,我们每次就直接暴力枚举n个数中的两个数,然后进行加减乘除就好了,然后将这两个数变成新的一个数,然后dfs(n-1)就好了,这样不停的递归下去。

  • 暴力写出所有情况

    a[1]+a[2]+a[3]+a[4]

    a[1]+a[2]+a[3]-a[4]

code :                                                                                                                                            

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
double v[4];
bool dfs(int n) {
     if(n == 1)  {
         if(fabs(v[0] - 24) < 1e-6) return true;
         else  return false;
     }
     else{
          for(int i = 0; i < n; ++i)
             for(int j = i + 1;j < n; ++j) {
             	double x1 = v[i];
                double x2 = v[j];
                v[j] = v[n - 1];  //将后面的数提到前面来
                v[i] = x1 + x2; if(dfs(n - 1))  return true;
                v[i] = x1 * x2; if(dfs(n - 1))  return true;
                v[i] = x1 - x2; if(dfs(n - 1))  return true;
                v[i] = x2 - x1; if(dfs(n - 1))  return true;
                if(x1){  v[i] = x2/x1; if(dfs(n - 1)) return true; }
                if(x2){  v[i] = x1/x2; if(dfs(n - 1)) return true; }
                //对于数v[j]没有满足条件,所以还原原来的数
                v[i] = x1;
                v[j] = x2;
             }
     }
    //都不满足的话,就返回false
     return false;
}

int main(void) {
    int T;
    cin>>T;
    while(T--) {
         cin >> v[0] >> v[1] >> v[2] >> v[3];
         if(dfs(4))
         	cout<<"Yes" << endl;
         else
            cout<<"No" << endl;
    }

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值