Chinese Mahjong UVA - 11210
題意:
要你寫一個程式,判斷是否“聽”牌。
“聽”牌有兩個将,有(0)多個刻子(相同的),有(0)多個順子(同花相連)。
思路:
- 枚舉剩下的那張是34種裡的哪一張即可。(現在有13張手牌,差一張。)
一種牌最多有四張。注意
- 之後遞歸+回溯判斷是否**“聽”牌**即可。
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;
}