进阶实验2-3.2 用扑克牌计算24点 (25分)

一副扑克牌的每张牌表示一个数(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


#include <cstdio>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
int s[5],num[5],flag,vis[4];
char o[5] = "+-*/",c[4];
int com(int a,int b,char op) {
    switch(op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return b && a % b == 0 ? a / b : inf;
    }
}
bool m1() {
    int d = com(s[0],s[1],c[0]);;
    d = com(d,s[2],c[1]);
    d = com(d,s[3],c[2]);
    if(d == 24) printf("((%d%c%d)%c%d)%c%d",s[0],c[0],s[1],c[1],s[2],c[2],s[3]);
    return d == 24;
}
bool m2() {
    int d = com(s[0],s[1],c[0]),e = com(s[2],s[3],c[2]);
    d = com(d,e,c[1]);
    if(d == 24) printf("(%d%c%d)%c(%d%c%d)",s[0],c[0],s[1],c[1],s[2],c[2],s[3]);
    return d == 24;
}
bool m3() {
    int d = com(s[2],s[3],c[2]);;
    d = com(s[1],d,c[1]);
    d = com(s[0],d,c[0]);
    if(d == 24) printf("%d%c(%d%c(%d%c%d))",s[0],c[0],s[1],c[1],s[2],c[2],s[3]);
    return d == 24;
}
void dfs1(int k) {
    if(flag) return;
    if(k >= 4) {
        flag |= m1() || m2() || m3();
        return;
    }
    for(int i = 0;i < 4;i ++) {
        if(vis[i]) continue;
        vis[i] = 1;
        s[k] = num[i];
        dfs1(k + 1);
        vis[i] = 0;
    }
}
void dfs(int k) {
    if(flag) return;
    if(k >= 3) {
        dfs1(0);
        return;
    }
    for(int i = 0;i < 4;i ++) {
        c[k] = o[i];
        dfs(k + 1);
    }
}
int main() {
    for(int i = 0;i < 4;i ++) {
        scanf("%d",&num[i]);
    }
    dfs(0);
    if(!flag) printf("-1");
    return 0;
}
原文地址:https://www.cnblogs.com/8023spz/p/12307892.html