题目大意:
求出所有可以听的牌
思路:
暴力枚举,回溯
代码:
#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;
}