一副扑克牌的每张牌表示一个数(J、Q、K 分别表示 11、12、13,两个司令都表示 6)。任取4 张牌,即得到 4 个 1~13 的数,请添加运算符(规定为加+ 减- 乘* 除/ 四种)使之成为一个运算式。每个数只能参与一次运算,4 个数顺序可以任意组合,4 个运算符任意取 3 个且可以重复取。运算遵从一定优先级别,可加括号控制,最终使运算结果为 24。请输出一种解决方案的表达式,用括号表示运算优先。如果没有一种解决方案,则输出 -1 表示无解。
输入格式:
输入在一行中给出 4 个整数,每个整数取值在 [1, 13]。
输出格式:
输出任一种解决方案的表达式,用括号表示运算优先。如果没有解决方案,请输出 -1。
输入样例:
2 3 12 12
输出样例:
((3-2)*12)+12
暴力求解。
根据op1、op2和op3计算的优先顺序不同,共有5种计算组合形式:
op1->op2->op3 :((s1 op1 s2)op2 s3)op3 s4
op1->op3->op2 :(s1 op1 s2)op2(s3 op3 s4)
op2->op1->op3 :(s1 op1(s2 op2 s3))op3 s4
op2->op3->op1 :s1 op1((s2 op2 s3)op3 s4)
op3->op1->op2 :(s1 op1 s2)op2(s3 op3 s4)(与第2种情况相同)
op3->op2->op1 :s1 op1(s2 op2(s3 op3 s4))
既要考虑不同排列的4个数据,又要考虑不同的3个运算符选择,刚开始一团乱麻,本来想直接写一个函数直接列举出所有的情况,但是越写越乱。参考了别人的代码(https://www.cnblogs.com/snzhong/p/12585080.html),其实应该把上述5种计算组合形式分别编写5个函数,再穷举数字和运算符。
除法/的情况导致需要使用浮点型数据。
#include
using namespace std;
double result(double x, double y, char op)
{
double ret = 0;
switch (op)
{
case'+':
ret = x + y;
break;
case'-':
ret = x - y;
break;
case'*':
ret = x * y;
break;
case'/':
if (y != 0) { ret = 1.0*x / y; }
break;
}
return ret;
}
//((s1 op1 s2)op2 s3)op3 s4
double model1(int* s, char op1, char op2, char op3)
{
double x = result(s[0], s[1], op1);
double y = result(x, s[2], op2);
double z = result(y, s[3], op3);
return z;
}
//(s1 op1 s2)op2(s3 op3 s4)
double model2(int* s, char op1, char op2, char op3)
{
double x = result(s[0], s[1], op1);
double y = result(s[2], s[3], op3);
double z = result(x, y, op2);
return z;
}
//(s1 op1(s2 op2 s3))op3 s4
double model3(int* s, char op1, char op2, char op3)
{
double x = result(s[1], s[2], op2);
double y = result(s[0], x, op1);
double z = result(y, s[3], op3);
return z;
}
//s1 op1((s2 op2 s3)op3 s4)
double model4(int* s, char op1, char op2, char op3)
{
double x = result(s[1], s[2], op2);
double y = result(x, s[3], op3);
double z = result(s[0], y, op1);
return z;
}
//s1 op1(s2 op2(s3 op3 s4))
double model5(int* s, char op1, char op2, char op3)
{
double x = result(s[2], s[3], op3);
double y = result(s[1], x, op2);
double z = result(s[0], y, op1);
return z;
}
bool cal(int* a, char* op)
{
int i, j, k;
//穷举运算符
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
for (k = 0; k < 4; k++)
{
if (model1(a, op[i], op[j], op[k]) == 24)
{
cout << "((" << a[0] << op[i] << a[1] << ")" << op[j] << a[2] << ")" << op[k] << a[3];
return 1;
}
else if (model2(a, op[i], op[j], op[k]) == 24)
{
cout << "(" << a[0] << op[i] << a[1] << ")" << op[j] << "(" << a[2] << op[k] << a[3] << ")";
return 1;
}
else if (model3(a, op[i], op[j], op[k]) == 24)
{
cout << "(" << a[0] << op[i] << "(" << a[1] << op[j] << a[2] << "))" << op[k] << a[3];
return 1;
}
else if (model4(a, op[i], op[j], op[k]) == 24)
{
cout << a[0] << op[i] << "((" << a[1] << op[j] << a[2] << ")" << op[k] << a[3] << ")";
return 1;
}
else if (model5(a, op[i], op[j], op[k]) == 24)
{
cout << a[0] << op[i] << "(" << a[1] << op[j] << "(" << a[2] << op[k] << a[3] << "))";
return 1;
}
}
}
}
return 0;
}
int main()
{
int* s = new int[4];
int ret;
int i, j, k, l;
for (i = 0; i < 4; i++)
{
cin >> s[i];
}
char op[4] = { '+','-','*','/' };
int *a = new int[4];
//穷举数字
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (j == i)continue;
for (k = 0; k < 4; k++)
{
if (k == i || k == j)continue;
for (l = 0; l < 4; l++)
{
if (l == i || l == j || l == k)continue;
a[0] = s[i]; a[1] = s[j]; a[2] = s[k]; a[3] = s[l];
ret = cal(a, op);
if (ret) { break; }
}
if (ret) { break; }
}
if (ret) { break; }
}
if (ret) { break; }
}
if (ret == 0) { cout << -1; }
return 0;
}