進階實驗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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM