題意:這個題意。有點麻煩,就是說給定13張牌,讓你求能“聽”的牌。(具體的見原題)
原題鏈接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2151
析:看到這個題,真是麻煩啊,我又不懂麻將,看了好久才明白什么是“聽”。分析一下思路。
首先對所有的牌都進行編號,然后暴力,首先的是先判斷是哪個是將,然后再進一步判斷,
哪一個是刻子,和順子,用遞歸很簡單的,只要全搜一下就好。整體不難,容易理解。
注意的是有的牌已經四張了,就不能再“聽”了,這是一個坑。
代碼如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 15 + 5;
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 c[35], id[15];
char s[100];
int getid(const char *s){//獲得每張牌的id
for(int i = 0; i < 34; ++i)
if(!strcmp(mahjong[i], s)) return i;
return -1;
}
bool dfs(int d){
for(int i = 0; i < 34; ++i) if(c[i] > 2){//刻子
if(3 == d) return true;//除了將,那么刻子和順子的和應該是4個,所以這就已經判斷安然無恙了
c[i] -= 3;
if(dfs(d+1)){ c[i] += 3; return true; }//找到時,要注意把c[i]改回來
c[i] += 3;
}
for(int i = 0; i < 24; ++i)
if(i % 9 <= 6 && c[i] > 0 && c[i+1] > 0 && c[i+2] > 0) {//順子
if(3 == d) return true;//同上
--c[i]; --c[i+1]; --c[i+2];
if(dfs(d+1)){ ++c[i]; ++c[i+1]; ++c[i+2]; return true; }//同上
++c[i]; ++c[i+1]; ++c[i+2];
}
return false;
}
bool judge(){
for(int i = 0; i < 34; ++i) if(c[i] > 1){//暴力,一張一張判斷的,是不是將
c[i] -= 2;//判斷是將了
if(dfs(0)){ c[i] += 2; return true; }//成立,要把c[i]改回來
c[i] += 2;
}
return false;//不成立
}
int main(){
// freopen("in.txt", "r", stdin);
int kase = 0;
bool ok;
while(scanf("%s", s) == 1){
if('0' == s[0]) break;
id[0] = getid(s);
for(int i = 1; i < 13; ++i){
scanf("%s", s);
id[i] = getid(s);//獲得id
// printf("%d %d\n", i, id[i]);
}
// printf("\n");
ok = false;
memset(c, 0, sizeof(c));//每次要清空
for(int i = 0; i < 13; ++i) ++c[id[i]];//獲得每張牌的數量
// puts("++");
printf("Case %d:", ++kase);
for(int i = 0; i < 34; ++i){
if(c[i] > 3) continue;//如果這張牌已經四張了,就不能再聽了,是坑
++c[i];
if(judge()){
ok = true;
printf(" %s", mahjong[i]);//輸出
}
--c[i];
}
if(!ok) printf(" Not ready");
printf("\n");
}
return 0;
}
