uva11210

题目大意:
求出所有可以听的牌

思路:
暴力枚举,回溯

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
const char *mj[] = {
    "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 cnt[34], f[13];
char s[100];
int find(char *str) {
    for(int i = 0; i < 34; i++)
        if(strcmp(str,mj[i]) == 0) return i;
    return -1;
}
bool dfs(int d) { //找刻子和顺子
    if(d == 4)return true;
    for(int i = 0 ; i < 34; i++) {
        if(cnt[i] < 3) continue;
        cnt[i] -= 3;
        if(dfs(d + 1)) return true;
    // dfs(d + 1);
        cnt[i] += 3;
    }
    for(int i = 0; i <= 24; i++) {
        if(i % 9 <= 6 & cnt[i] >= 1 && cnt[i + 1] >= 1 && cnt[i + 2] >= 1) {
            cnt[i] --;
            cnt[i + 1] --;
            cnt[i + 2]--;
            if(dfs(d + 1)) return true;
// dfs(d + 1);
            cnt[i] ++;
            cnt[i + 1] ++;
            cnt[i + 2] ++;
        }
    }
    return false;
}
bool judge() { //找将
    for(int i = 0; i < 34; i++) {
        if(cnt[i] < 2) continue;
        cnt[i] -= 2;
        if(dfs(0)) return true;
        cnt[i] += 2;
    }
    return false;
}
void solve() { //添加一个
    int flag = 0;
    for(int i = 0 ; i < 34; i++) {
        memset(cnt,0,sizeof(cnt));
        for(int j = 0; j < 13; j++){
            cnt[f[j]]++;
        }
        if(cnt[i] >= 4) continue;
        cnt[i]++;
        if(judge()) {
            flag = 1;
            printf(" %s",mj[i]);
        }
        cnt[i]--;
    }
    if(flag) printf("\n");
    else
        printf(" Not ready\n");
}
int main() {

    int cases = 1;
    while(~scanf("%s",s) && s[0]!= '0') {
        f[0] = find(s);
        for(int i = 1; i < 13; i++) {
            scanf("%s",s);
            f[i] = find(s);
        }
        printf("Case %d:",cases++);
        solve();
    }
    return 0;
}

你可能感兴趣的:(uva11210)