11210 - Chinese Mahjong

题目链接: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 40
char 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;    
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章