hdu 4431&3391 Mahjong 枚举,判断

hdu 4431 Mahjong
3391也是差不多的题,但是没有字牌应该简单一点.
我说这个题是一个暴力应该没什么问题,就是判断的时候非常麻烦.

题意

说说打的是日本麻将,不过好像中国的麻将也都是这么玩的.

不超过20000组数据,每组数据给你一手13张麻将牌,你要摸一张牌.问你摸哪些牌来能胡.如果这手牌还没有听牌输出"Nooten".

思路

思路很简单了,枚举摸上来哪一张牌然后判断能不能胡.七对子和十三幺应该也是比较好特判的.
实现上稍微有点难度.

/*
七对子十三幺可以直接判,其它情况先枚举哪一对是将牌,然后判断剩下的牌能否组成4组.
注意不能杠,所以已经摸到4张的牌就不能判了.
如果使用搜索算法,必须要有非常强大的剪枝.这题的剪枝非常的多,随便就可以剪掉很大一部分.
*/
#include<bits/stdc++.h>
using namespace std;
int s[40],t,res[99];//s[]是桶,存放每种牌有几张.

int qidui()//七对子:必须有7种牌,每种牌各两张(豪华七对?不存在的)
{
int r=0,i;
for (i=1;i<=34;++i) r+=s[i]==2;
return r==7;
}

int shisanyao()//十三幺:一九万,一九条,一九筒,字牌必须都有,其它牌必须都没有
{
int i;
for (i=2;i<=8;++i) if (s[i]) return 0;
for (i=11;i<=17;++i) if (s[i]) return 0;
for (i=20;i<=26;++i) if (s[i]) return 0;
for (i=28;i<=34;++i) if (!s[i]) return 0;
return s[1]&&s[9]&&s[10]&&s[18]&&s[19]&&s[27];
}

int qita()
{
int tmp[40],i;
memcpy(tmp,s,sizeof s);//把s复制给tmp
for (i=1;i<=34;i++)
  {
  if (tmp[i]>=3) tmp[i]-=3;//刻子可以直接去掉,如果它能组成顺子的话肯定已经在前面被贪心的选掉了.
  for (;tmp[i];)
    {
    if (i<=27&&i%9<=7&&i%9!=0&&tmp[i]&&tmp[i+1]&&tmp[i+2]) --tmp[i],--tmp[i+1],--tmp[i+2]; //字牌不能组成顺子,只能枚举到7这么大
    else return 0;
    }
  }
return 1;
}

int hu()//枚举将牌
{
int w=0,i;
for (i=1;i<=34;++i) if (s[i]>1)//大于等于两张
  {
  s[i]-=2;//去掉
  if (qita()) return s[i]+=2,1;//判断其它牌
  s[i]+=2;//回溯
  }
return 0;
}

//一万到九万用1-9表示,一条到九条用10-18表示,一筒到九筒用19-27表示,字牌用28-34表示.
int main()
{
int i;
for (scanf("%d",&t);t--;puts(""))
  {
  memset(s,0,sizeof s);
  for (i=0;i<13;i++)
    {
    char c[9];
    scanf("%s",c);
    s[c[0]-48+(c[1]=='s'?1:c[1]=='p'?2:c[1]=='c'?3:0)*9]++;//搞一下放入桶
    }
  int ans=0;
  for (i=1;i<35;++i) if (s[i]<4)//枚举摸上来不超过4张的牌
    {
    ++s[i];//把这张牌摸进来
    if (hu()||qidui()||shisanyao()) res[++ans]=i;//符合胡的条件它就是一个解
    --s[i];//回溯
    }
  if (!ans) printf("Nooten");//没有答案.
  else //输出答案
    {
    printf("%d",ans);
    for (i=1;i<=ans;++i)
      {
      int t=res[i];
      if (t<=9) printf(" %dm",t);
      else if (t<=18) printf(" %ds",t-9);
      else if (t<=27) printf(" %dp",t-18);
      else printf(" %dc",t-27);
      }
    }
  }
}

这题恶心极了,但麻将毕竟是国粹,搞一搞也未必是坏事.

猜你喜欢

转载自blog.csdn.net/qq_31908675/article/details/79443571