题意:
给出13张牌,判断是否听牌
思路:
一共34种牌,一一枚举,看是否会胡
每成一个序列use就加相应个数,如果use可达14个就可胡牌
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
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 cnt[35];
int use;
bool ok;
int change(char* p) {
for(int i=0; i<34; i++)
if(strcmp(p, mahjong[i]) == 0) return i;
}
bool judge(int i) {
if(0<=i && i<=6) return true;
if(9<=i && i<=15) return true;
if(18<=i && i<=24) return true;
return false;
}
bool dfs(int cur) {
if(use == 14) {
ok = true;
return true;
}
if(cur >= 34) return false;
if(cnt[cur] == 0) return dfs(cur+1);//这里要注意只有当这种牌用完全部配对了才能进入下一个牌
bool ok2 = false;
if(cnt[cur] >= 3) {
cnt[cur] -= 3;
use += 3;
if(dfs(cur)) ok2 = true;
cnt[cur] += 3;
use -= 3;
}
if(!ok2 && judge(cur) && cnt[cur] && cnt[cur+1] && cnt[cur+2]) {
cnt[cur]--, cnt[cur+1]--, cnt[cur+2]--;
use += 3;
if(dfs(cur)) ok2 = true;
use -= 3;
cnt[cur]++, cnt[cur+1]++, cnt[cur+2]++;
}
return ok2;
}
int main() {
char mj[10];
int kase=0;
while(scanf("%s", mj) && strcmp("0", mj)) {
printf("Case %d:", ++kase);
memset(cnt, 0, sizeof(cnt));
++cnt[change(mj)];
ok = false;
for(int i=0; i<12; i++) {
scanf("%s", mj);
++cnt[change(mj)];
}
for(int i=0; i<34; i++) {
if(cnt[i] == 4) continue;
cnt[i]++;
for(int j=0; j<34; j++) {
use = 0;
bool ok3 = false;
if(cnt[j] >= 2) {
cnt[j] -= 2;
use += 2;
if(dfs(0)) {
ok3 = true;
printf(" %s", mahjong[i]);
}
cnt[j]+=2;
}
if(ok3) break;
}
cnt[i]--;
}
if(ok) printf("\n");
else printf(" Not ready\n");
}
return 0;
}