天天看點

Chinese Mahjong UVA - 11210(暴力dfs加回溯)Chinese Mahjong UVA - 11210 題意:思路:AC

Chinese Mahjong UVA - 11210

題意:

要你寫一個程式,判斷是否“聽”牌。

“聽”牌有兩個将,有(0)多個刻子(相同的),有(0)多個順子(同花相連)。

思路:

  1. 枚舉剩下的那張是34種裡的哪一張即可。(現在有13張手牌,差一張。)

    注意

    一種牌最多有四張。
  2. 之後遞歸+回溯判斷是否**“聽”牌**即可。

AC

#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
const char* mahjong[]={
    "1T","2T","3T","4T","5T","6T","7T","8T","9T",
    "1S","2S","3S","4S","5S","6S","7S","8S","9S",
    "1W","2W","3W","4W","5W","6W","7W","8W","9W",
    "DONG","NAN","XI","BEI",
    "ZHONG","FA","BAI"
};
int idc(char *s){
    fori(i,0,34)if(strcmp(mahjong[i],s) == 0)return i;
    return -1;
}
int c[34], mj[15];
bool dfs(int dep){
    ///刻子
    fori(i,0,34){
        if(c[i]>=3){
            c[i] -= 3;
            if(dep==3)return true;
            if(dfs(dep+1))return true;
            c[i] += 3;
        }
    }
    fori(i,0,24){
        if(i%9<=6 && c[i]>=1 && c[i+1]>=1 && c[i+2]>=1){
            if(dep==3) return true;
            c[i] -= 1; c[i+1] -= 1; c[i+2] -= 1;
            if(dfs(dep+1)) return true;
            c[i] += 1; c[i+1] += 1; c[i+2] += 1;
        }
    }
    return false;
}
bool check(){
    fori(i,0,34){
        if(c[i]>=2){
            c[i] -= 2;
            if(dfs(0)) return true;
            c[i] += 2;
        }
    }
    return false;
}
int main()
{
    //ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    char s[100];
    int caseno = 0;
    while(scanf("%s", s)){
        if(s[0] == '0')break;
        mj[0] = idc(s);
        fori(i,1,13)scanf("%s", s), mj[i] = idc(s);
        bool ok = false;
        printf("Case %d:", ++caseno);
        fori(i,0,34){
            mst(c,0);
            fori(j,0,13)c[mj[j]]++;
            if(c[i]>=4)continue;
            c[i]++;
            if(check()){
                printf(" %s", mahjong[i]);
                ok = true;
            }
            c[i]--;
        }
        if(!ok)printf(" Not ready");
        printf("\n");
    }
    return 0;
}

           

繼續閱讀