11210 - Chinese Mahjong

来源:互联网 发布:电工绘图软件 编辑:程序博客网 时间:2024/06/05 06:10

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=456&problem=2151&mosmsg=Submission+received+with+ID+12192438

题目大意:中国麻将,输入13张牌,输出你是否听牌,若听牌输出你听哪些牌。

题目思路:暴力,依次枚举34张牌,即判断当你手中多了这张牌后是否糊牌!判断是否糊牌,首先剔除一对将,然后在每三张牌组合,牌的组合有多种,可以是顺子,也可以是刻子,判断时可以将刻子和顺子分开判断。


#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 40char sname[34][6]={  "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"};char name[10];int cnt[MAX],tot[MAX];int set_read(char *s){    for (int i=0;i<34;i++)    {        if (strcmp(s,sname[i])==0)           return i;    }}int dfs(int x){    int i,j;    //分刻子与顺子处理,因为有些牌不存在顺子     for (i=0;i<34;i++)    {        if (cnt[i]>=3)        {           if (x==3)              return 1;           cnt[i]-=3;           if (dfs(x+1)) //当不成立时回溯。               return 1;           cnt[i]+=3;        }     }    for (i=0;i<=24;i++)    {        if (i%9<7&&cnt[i]>0&&cnt[i+1]>0&&cnt[i+2]>0)        {           cnt[i]--;           cnt[i+1]--;           cnt[i+2]--;           if (x==3)                                              return 1;           if (dfs(x+1))              return 1;           cnt[i]++;           cnt[i+1]++;           cnt[i+2]++;                                                    }       }    return 0;}int check(){    int i;    for (i=0;i<34;i++)    {        if (cnt[i]>=2)        {           cnt[i]-=2;                         if (dfs(0))              return 1;           cnt[i]+=2;        }        }    return 0;}int main(){    int k=1;    while (scanf("%s",name)!=EOF)    {          if (strcmp(name,"0")==0)             break;                int i=0,j,x,ok=1;          x=set_read(name);          tot[i]=x;          for (i=1;i<13;i++)          {              scanf("%s",name);              x=set_read(name);              tot[i]=x;;          }             printf("Case %d:",k++);          //for (i=0;i<13;i++)              //printf("%d ",tot[i]);          //printf("\n");          for (i=0;i<34;i++)          {              memset(cnt,0,sizeof(cnt));              for (j=0;j<13;j++)                  cnt[tot[j]]++;              if (cnt[i]>=4)                 continue;              cnt[i]++;              if (check())              {                 printf(" %s",sname[i]);                  ok=0;              }              cnt[i]--;          }           if (ok)          {             printf(" Not ready");                 }            printf("\n");    }        return 0;    }