题目描述 Description
superwyh是一个非常疯狂的24点爱好者,空闲时总是自己拿出扑克来算24点,24点的规则很简单,就是给你4张扑克(从1至13,用A代替1,J代替11,Q代替12,K代替13)通过加减乘除来求得24,各位oier帮了superwyh好多忙,为了报答大家superwyh就和大家做个24点的游戏,superwyh给大家4张牌大家告诉superwyh能不能凑成24就行。
[renqing PS:这道题很easy,是送分的题]
输入描述 Input Description
输入格式4张牌的牌面(1<=n<=13)。
输出描述 Output Description
输出格式如果能凑成输出”yes”反之输出”no”。
样例输入 Sample Input
A 2 3 4
样例输出 Sample Output
yes
数据范围及提示 Data Size && Hint
1 < = n < = 13 1<=n<=13 1<=n<=13
解题思路 Solve Idea
这里我们看到应该可以反映过来,这是一个搜索的题目,那么遇到搜索题目首先我们应该怎么做呢?当然是找到问题的解空间,这里的解空间是什么呢?当然是4张牌和四则运算组合而成的所有表达式,有了这个思路,我们就可以开始暴力搜索了。
**坑点:**这里有一个大坑就是除法计算可能会出现浮点误差和出现浮点数,所以我们要对sum使用double类型的,然后对sum判断浮点误差。
代码 Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 105;
const int INF = 0x3f3f3f3f;
bool used[5];
int a[5], card[5];
const double eps = 1e-6;
bool dfs(int cur, double sum)
{
if(cur == 4) {
if(fabs(sum - 24.0) <= eps) return true; // 这题的除法可能会有浮点数误差,所以sum要用double类型
return false;
}
for(int i = 0; i < 4; ++i) {
if(used[i]) continue;
used[i] = true;
if(dfs(cur + 1, sum + card[i])) return true;
if(dfs(cur + 1, sum - card[i])) return true;
if(dfs(cur + 1, card[i] - sum)) return true;
if(sum && dfs(cur + 1, sum * card[i])) return true;
if(sum && dfs(cur + 1, sum / card[i])) return true;
if(sum && dfs(cur + 1, card[i] / sum)) return true;
used[i] = false;
}
return false;
}
int main()
{
for(int i = 0; i < 4; ++i) {
string s;
cin >> s;
if(s[0] == 'A') card[i] = 1;
else if(s[0] == 'J') card[i] = 11;
else if(s[0] == 'Q') card[i] = 12;
else if(s[0] == 'K') card[i] = 13;
else if(s[0] == '1' && card[1] == '0') card[i] = 10;
else card[i] = s[0] - '0';
}
if(dfs(0, 0)) puts("yes");
else puts("no");
return 0;
}