HDU 4431 Mahjong(神奇的麻将) 模拟

胡牌的情况

1、有1对相同的牌(对子),和4组meld(对不起我实在不知道怎么翻译了)。meld就是3张相同的牌或者3张连续的牌(顺子)。注意3张连续的c牌不能看做meld。

2、有7对不同的对子。

3、有1s,9s,1m,9m,1p,9p,和1c至7c这13种牌,并且其中有1种牌有2张。

做法是枚举1张牌加入牌组(第14张牌),然后判断当前牌组能不能胡。

对于第一种胡牌情况,先选出1对对子,在判断剩下的是不是4组meld.

对于第二、三种情况就直接判断了。

需要注意的是,每种牌最多只有4张,需要在每次枚举时判一下。(我卡在这好久)

以及这道题每行输出末尾如果有空格好像会PE。(啊。。。)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 40
using namespace std;
int q[maxn],ans;
bool jud0(int c[])
{
    int i,cnt[maxn];
    for (i=1;i<=37;i++) cnt[i]=c[i];
    for (i=1;i<30;i++)
    {    
        if (i%10==0) continue;
        if (cnt[i]>=3) cnt[i]-=3;
        if (cnt[i]>0 && i%10<8) 
        {
            cnt[i+1]-=cnt[i];
            cnt[i+2]-=cnt[i];
            cnt[i]=0;
        }
        if (cnt[i]!=0) return 0;
    }
    for (i=31;i<=37;i++)
    {
        if (cnt[i]>=3) cnt[i]-=3;
        if (cnt[i]!=0) return 0;
    }
    return 1;
}
bool jud1(int c[])
{
    int i,tot=0,cnt[maxn];
    for (i=1;i<=37;i++) cnt[i]=c[i];
    for (i=1;i<=37;i++)
        if (cnt[i]>=2) tot++;
    if (tot==7) return 1;
    return 0;
}
bool jud2(int c[])
{
    int i,flag=1,tot=0,cnt[maxn];
    for (i=1;i<=37;i++) cnt[i]=c[i];
    for (i=0;i<3;i++)
        if (!cnt[i*10+1] || !cnt[i*10+9]) flag=0;
        else tot+=cnt[i*10+1]+cnt[i*10+9];
    for (i=1;i<=7;i++) 
        if (!cnt[30+i]) flag=0;
        else tot+=cnt[30+i];
    if (flag && tot==14) return 1;
    return 0;    
}
int main()
{
    int i,j,t,tmp,c[maxn],flag;
    char s[10];
    scanf("%d",&t);
    while (t--)
    {
        memset(c,0,sizeof(c));
        ans=0;flag=1;
        for (i=1;i<14;i++)
        {
            scanf("%s",s);
            if (s[1]=='m') tmp=s[0]-'0';
            if (s[1]=='s') tmp=s[0]-'0'+10;
            if (s[1]=='p') tmp=s[0]-'0'+20;
            if (s[1]=='c') tmp=s[0]-'0'+30; 
            c[tmp]++;
            if (c[tmp]>4) flag=0;
        }
        if (!flag) 
        {
            printf("Nooten
");
            continue;
        }
        for (i=1;i<=37;i++)
        {
            if (i%10==0 || c[i]>3) continue;
            c[i]++;flag=0;
            for (j=1;j<=37;j++) 
                if (c[j]>=2 && j%10!=0 && !flag)
                {
                    c[j]-=2;
                    if (!flag && jud0(c)) 
                    {
                        q[++ans]=i;flag=1;
                    }
                    c[j]+=2;
                }
            if (!flag) 
            {
                if (jud1(c)|| jud2(c)) q[++ans]=i;
            }
            c[i]--;
        }
        if (ans==0) printf("Nooten
");
        else 
        {
            printf("%d",ans);
            for (i=1;i<=ans;i++) 
            {
                if (q[i]>30) printf(" %dc",q[i]-30);
                else if (q[i]>20) printf(" %dp",q[i]-20);
                else if (q[i]>10) printf(" %ds",q[i]-10);
                else printf(" %dm",q[i]);
            }
            printf("
");
        }
    }
    return 0;
} 

(写得我累死了)

原文地址:https://www.cnblogs.com/lsykk/p/12185950.html