UVa 11210 - Chinese Mahjong

解题报告:麻将的规则这里就不说了,这题我们可以用暴力的方法,所以我们应该这样枚举,即将34张牌的每一张牌都放到原来的十三张牌里面去,所以这时我们只要判断这十四张牌能不能胡,因为若要胡的话一定要有一个对子,所以这个时候我们应该枚举到底用哪一种牌作为对子,不过还要先判断这种牌的数量是不是大于2,如果大于2说明这种牌可以作为对子。接下来就是判断这十四张牌到底能不能胡的问题。对于这个问题我们可以先把输入的字符串先转化成0到33的对应的数字模式,即0对应1T,1对应2T ...... 33对应BAI,这样我们可以从数字最小的牌开始判断,从0开始,然后分为以下几种情况,第一,这种牌的数量为0,做法是直接跳到下一种牌;第二,这种牌的数量大于等于3,做法是把这种牌作为刻子;第三,这种牌的数量小于3且大于0,这时我们判断从这张牌开始的三张牌以内,这三种牌的数量是否都是大于等于1,如果是,我们就将这三张牌作为顺子,然后把这三种牌的数量分别减少1。如果这三种情况都不满足,直接返回不可以胡。

 1 #include<cstdio>
 2 #include<cstring>
 3 const char feng[50][10]={"","DONG","NAN","XI","BEI","ZHONG","FA","BAI"};
 4 const char hua[50][3]={"T","S","W"};
 5 int mj[40];
 6 int judge(char *p) {
 7     if(p[0]>='0'&&p[0]<='9') {
 8         if(p[1]=='T')
 9         return (p[0]-'0'-1);
10         else if(p[1]=='S')
11         return (8+p[0]-'0');
12         else return (17+p[0]-'0');
13     }
14     else {
15         for(int i=1;i<=7;++i)
16         if(!strcmp(feng[i],p))
17         return (26+i);
18     }
19 }
20 
21 bool search(int dep) {
22     int i;
23     for(i=0;i<34;++i)
24     if(mj[i]>=3) {
25         if(dep==3) return true;
26         mj[i]-=3;
27         if(search(dep+1)) return true;
28         mj[i]+=3;
29     }
30     for(i=0;i<=24;++i)
31     if(i%9<=6&&mj[i]>=1&&mj[i+1]>=1&&mj[i+2]>=1) {
32         if(dep==3) return true;
33         mj[i]--; mj[i+1]--;mj[i+2]--;
34         if(search(dep+1)) return true;
35         mj[i]++; mj[i+1]++; mj[i+2]++;
36     }
37     return false;
38 }
39 
40 bool check() {
41     for(int i=0;i<34;++i)
42     if(mj[i]>=2) {
43         mj[i]-=2;
44         if(search(0)) return true;
45         mj[i]+=2;
46     }
47     return false;
48 }
49 int main() {
50     char str[10];
51     int majiang[14],Case=1; 
52     while(scanf("%s",str)&&str[0]!='0') {
53         majiang[0]=judge(str);
54         int flag=0;
55         printf("Case %d:",Case++);
56         for(int i = 0; i<12;++i) {
57             scanf("%s",str);
58             majiang[i+1]=judge(str);
59         }
60         for(int i=0;i<34;++i) {
61             memset(mj,0,sizeof(mj));
62             for(int j=0;j<13;++j)
63             mj[majiang[j]]++;
64             if(mj[i]>=4)
65             continue;
66             mj[i]++;
67             if(check()) {
68                 flag=1;
69                 if(i>=0&&i<=26)
70                 printf(" %d%s",(i%9+1),hua[i/9]);
71                 else printf(" %s",feng[i-26]);
72             }
73         }
74         if(!flag)
75         printf(" Not ready");
76         printf("\n");
77     }
78     return 0;
79 }
View Code

 

 

posted @ 2013-06-20 22:20  xiaxiaosheng  阅读(456)  评论(0编辑  收藏  举报