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;    
}


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