搜索一·24点(hiho98)

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

周末,小Hi和小Ho都在家待着。

在收拾完房间时,小Ho偶然发现了一副扑克,于是两人考虑用这副扑克来打发时间。

小Ho:玩点什么好呢?

小Hi:两个人啊,不如来玩24点怎么样,不靠运气就靠实力的游戏。

小Ho:好啊,好啊。

<经过若干局游戏之后>

小Ho:小Hi,你说如果要写个程序来玩24点会不会很复杂啊?

小Hi:让我想想。

<过了几分钟>

小Hi:我知道了!其实很简单嘛。

输入

第1行:1个正整数, t,表示数据组数,2≤t≤100。

第2..t+1行:4个正整数, a,b,c,d,1≤a,b,c,d≤10。

输出

第1..t行:每行一个字符串,第i行表示第i组能否计算出24点。若能够输出"Yes",否则输出"No"。

样例输入
2
5 5 5 1
9 9 9 9
样例输出
           Yes
 No



什么是24点
这里有Hiho的解释,不过我是直接暴力的。


(((a ⊙ b) ⊙ c ) ⊙ d)

((a ⊙ b) ⊙ (c ⊙ d))



小Ho:恩..(小Ho思考了一下)..好像确实是这样。

小Hi:既然我们已经找到了固定的模式,那么剩下的就比较简单了。

将4张牌的值,分别代入a,b,c,d,再把可能的运算符也代入。就可以得到相应的计算式子,将其计算出来,再检查结果是否等于24。

那么小Ho,你觉得有多少种情况呢?

小Ho:由于我们有4个数,所以对于a,b,c,d的对应关系有4!=24种情况。3个运算符,每个运算符可能有6种情况,那就是6^3=216。再考虑到2种不同的模式,所以一共有2 * 24 * 216 = 10368种情况。

小Hi:你的计算中并没有考虑等价的情况,比如a + b 和 b + a,所以实际的情况数其实是小于10368种的。

不过由于对计算机而言,10368种情况数本来也不是很多,而要考虑等价反而显得比较麻烦。所以我们可以不要去考虑加法和乘法的可逆性,直接枚举所有的情况。

那么最后还是由小Ho你来给出参考的伪代码吧。

小Ho:嗯,这次的伪代码:



 

used[] = false
nowNumber[] =
{0,0,0,0} ops[] = {0,0,0} opType = {+,-,*,/,反-,反/} makeNumber(depth): If (depth >= 4) Then // 此时已经枚举完a,b,c,d // 开始枚举运算符 Return makeOperation(0) End If For i = 1 .. 4 If (not used[i]) Then // 每个数字只能使用一次 nowNumber[ depth ] = number[i] used[i] = true If (makeNumber(depth + 1)) Then Return True End If used[i] = false End If End For Return False makeOperation(depth): If (depth >= 3) Then // 此时已经枚举完a,b,c,d和三个运算符 // 计算在(((a ⊙ b) ⊙ c ) ⊙ d)形式下的值 If (calcType1(nowNumber, ops) == 24) Then Return true; End If // 计算在((a ⊙ b) ⊙ (c ⊙ d))形式下的值 If (calcType2(nowNumber, ops) == 24) Then Return true; End If Return false End If For i = 1 .. 6 ops[ depth ] = opType[i] If (makeOperation(depth + 1)) Then Return True End If End For Return False Main: input(number) used[] = false makeNumber(0)
     

     我的代码:   

/**************************************
*                                     *
*  -*- coding: utf-8 -*-              *
*  @Date    : 2016-05-16 11:11:21     *
*  @Author  : Zeroinger               *
*                                     *
 *************************************/
 #include <iostream>
 #include <cstring>
 #include <cmath>
 #include <queue>
 #include <stack>
 #include <list>
 #include <map>
 #include <set>
 #include <sstream>
 #include <string>
 #include <vector>
 #include <cstdio>
 #include <algorithm>
 using namespace std;
 double data[4];
 bool ok(double a,double b)
 {  
       if(fabs(a,b)<=1e-6)
          return true;
       return false;
 }
 bool DFS(int n)
 {
     bool flag=false;
     if(flag||(n==1&&ok(data[0],24)))
        return true;
     for(int i=0;i<n;i++)
     {
         for(int j=i+1;j<n;j++)
         {
             double t1=data[i];
             double t2=data[j];
             data[i]=t1+t2;
             data[j]=data[n-1];
             DFS(n-1);
             data[i]=t1-t2;
             DFS(n-1);
             data[i]=t2-t1;
             DFS(n-1);
             if(!ok(t1,0))
             {
                 data[i]=t2/t1;
                 DFS(n-1);
             }
             if(!ok(t2,0))
             {
                 data[i]=t1/t2;
                 DFS(n-1);
             }
             data[i]=t1;
             data[2]=t2;
         }
     }
 }
 int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf %lf %lf %lf", &data[0], &data[1], &data[2], &data[3]);
        flag = false;
        DFS(4);
        printf("%s
", flag ? "Yes" : "No");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Zeroinger/p/5497622.html