Problem Description
速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。
Input
每组输入数据占一行,给定四张牌。
Output
每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。
Sample Input
Sample Output
说实话,代码很丑。。。。
没想清楚就写,WA了很多次,4个数进行加减乘除运算,情况不多直接暴力。
运算需要注意的是:
1.除法要能整除才算
2.运算的顺序(这是关键)
开始只考虑了两两组合的运算顺序,WA,又补上从左到右依次算的顺序,依旧WA,发现没补全,
对于依次算的顺序我最后还是暴力处理的,所以最后写出来的代码实在丑
//Must so
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<cstring>
#include<ctype.h>
#include<queue>
#include<vector>
#include<set>
#include<cstdio>
#include<cmath>
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1<<29
#define NN 1000006
using namespace std;
const double PI = acos(-1.0);
typedef long long LL;
//找半天才发现我的Q Q 8 4这一组错了,这一组可以用((12+4)/8)*12得到
//而我只算了两两组合的情况。。。
//所以要补上一个一个按顺序来的情况
//。。。我的顺序排列似乎漏了某些情况。。。
// 2 8 7 5
bool vis[10];
string s[10];
int a[10];
int ans;
int getnum(string s)
{
if (s == "10") return 10;
if (isdigit(s[0])) return s[0] - 48;
if (s == "A") return 1;
if (s == "J") return 11;
if (s == "Q") return 12;
if (s == "K") return 13;
}
int fun(int x,int y,int i)
{
int mx = max(x,y);
int mn = min(x,y);
if (i == 1) return x+y;
if (i == 2) return x*y;
if (i == 3) return mx - mn;
if (i == 4)
{
if (mn&&mx%mn == 0) return mx/mn;
else return inf;
}
return inf;
}
bool div()//两两组合着算吧
{
int a1 = 0,a2,b1 = 0,b2;//a1 a2一组,b1 b2一组
for (int i = 0;i < 4;i++)
{
if (vis[i])
{
if (!a1) a1 = a[i];
else a2 = a[i];
}
else
{
if (!b1) b1 = a[i];
else b2 = a[i];
}
}
for (int i = 1;i <= 4;i++)
{
int aa = fun(a1,a2,i);
if (aa == inf) continue;
for (int j = 1;j <= 4;j++)
{
int bb = fun(b1,b2,j);
if (bb == inf) continue;
for (int k = 1;k <= 4;k++)
{
int ans = fun(aa,bb,k);
if (ans == 24)
{
//cout<<aa<<"----"<<bb<<endl;
return 1;
}
}
}
}
return 0;
}
bool fuck(int a,int b,int c,int d)
{
for (int i = 1;i <= 4;i++)
{
int bb = fun(a,b,i);
if (bb == inf) continue;
for (int j = 1;j <= 4;j++)
{
int cc = fun(bb,c,j);
if (cc == inf) continue;
for (int k = 1;k <= 4;k++)
{
int dd = fun(cc,d,k);
if (dd == 24) return 1;
}
}
}
return 0;
}
bool con()//按顺序来
{
for (int i = 0;i < 4 ;i++)
{
int aa = a[i];
for (int j = 0;j < 4;j++)
{
if (j == i) continue;
int bb = a[j];
for (int k = 0;k < 4;k++)
{
if (k == i||k == j) continue;
int cc = a[k];
for (int l = 0;l < 4;l++)
{
if (l == i||l == j|l == k) continue;
int dd = a[l];
if (fuck(aa,bb,cc,dd)) return 1;
}
}
}
}
return 0;
}
bool fd()
{
for (int i = 0;i < 4;i++)
{
vis[i] = 1;
for (int j = 0;j < 4;j++)
{
if (i == j) continue;
vis [j] = 1;
if (div()) return 1;
vis[j] = 0;
}
vis[i] = 0;
}
if (con()) return 1;
return 0;
}
int main()
{
while (cin>>s[0])
{
a[0] = getnum(s[0]);
for (int i = 1; i < 4; i++)
{
cin>>s[i];
a[i] = getnum(s[i]);
}
// for (int i = 0;i < 4;i++)
// cout<<a[i]<<endl;
mem(vis,0);
if (fd()) puts("Yes");
else puts("No");
}
return 0;
}