hdu 4431 Mahjong

原文链接: http://www.cnblogs.com/liulangye/archive/2012/11/03/2752805.html

http://acm.hdu.edu.cn/showproblem.php?pid=4431

幸亏哥有点麻将基础  提到三种和牌方式

1: 7个不同的对子 

2: 传说中的十三幺  m1,m9,s1,s9,p1,p9,c1,c2,c3,c4,c5,c6,c7 然后再多一张 可以是 前面那13张中的任意一张

3: 一个对子 外加 四个 (吃或碰)吃就是三张牌组成的顺子  碰就是三个牌一样

思路 :

枚举添加任意一张牌 但不能使某种牌的个数超过4

然后判定是否是和牌

判定第三种和牌时 先枚举去掉一个对子 然后看是否剩余的牌组成 四个 (吃或碰)

注意:

c1,c2,c3 像  东南西方这类的牌 没有顺子

自己写的时候是因为一个地方数组没有初始化 wa 了很久

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<iomanip>
using namespace std;

#define LL long long
const int INF=0x5fffffff;
const double FINF=1e9;
const int N=20;
int s[N];
int c[N];
int m[N];
int p[N];
vector<int>ans;
vector<char>ansc;
bool Two()
{
    for(int i=1;i<=9;++i)
    {
        if(c[i]!=0&&c[i]!=2)
        return false;
        if(m[i]!=0&&m[i]!=2)
        return false;
        if(p[i]!=0&&p[i]!=2)
        return false;
        if(s[i]!=0&&s[i]!=2)
        return false;
    }
    return true;
}
bool Spe()
{
    int t2=0;
    for(int i=1;i<=7;++i)
    {
        if(c[i]==2)
        ++t2;
        else if(c[i]!=1)
        return false;
    }
    if(m[1]==2)
    ++t2;
    else if(m[1]!=1)
    return false;
    if(m[9]==2)
    ++t2;
    else if(m[9]!=1)
    return false;
    if(s[1]==2)
    ++t2;
    else if(s[1]!=1)
    return false;
    if(s[9]==2)
    ++t2;
    else if(s[9]!=1)
    return false;
    if(p[1]==2)
    ++t2;
    else if(p[1]!=1)
    return false;
    if(p[9]==2)
    ++t2;
    else if(p[9]!=1)
    return false;
    if(t2!=1)
    return false;
    return true;
}
bool Func(int tmp[],int l)
{
    if(tmp[l]==1||tmp[l]==2||tmp[l]==4)
    {
        --tmp[l];
        if(tmp[l+1]==0) return false;
        else --tmp[l+1];
        if(tmp[l+2]==0) return false;
        else --tmp[l+2];
    }
    if(tmp[l]==3)
    tmp[l]=0;
    return true;
}
bool Meld()
{
    int s1[N],m1[N],p1[N];
    for(int i=1;i<N;++i)
    {
        if(c[i]!=0&&c[i]!=3)
        return false;
        s1[i]=s[i];
        p1[i]=p[i];
        m1[i]=m[i];
    }
    int l=1;
    while(l<=9)
    {
        if(!s1[l]&&!m1[l]&&!p1[l])
        {++l;continue;}
        if(!Func(s1,l))
        return false;
        if(!Func(m1,l))
        return false;
        if(!Func(p1,l))
        return false;
    }
    return true;
}
bool Normal()
{
    for(int i=1;i<=9;++i)
    {
        if(c[i]>=2)
        {
            c[i]-=2;
            if(Meld())
            {c[i]+=2;return true;}
            c[i]+=2;
        }
        if(p[i]>=2)
        {
            p[i]-=2;
            if(Meld())
            {p[i]+=2;return true;}
            p[i]+=2;
        }
        if(m[i]>=2)
        {
            m[i]-=2;
            if(Meld())
            {m[i]+=2;return true;}
            m[i]+=2;
        }
        if(s[i]>=2)
        {
            s[i]-=2;
            if(Meld())
            {s[i]+=2;return true;}
            s[i]+=2;
        }
    }
    return false;
}
bool Win()
{
    if(Two())
    return true;
    if(Spe())
    return true;
    if(Normal())
    return true;
    return false;
}
void Fans(int stmp[],char k)
{
    int w=9;
    if(k=='c')
    w=7;
    for(int i=1;i<=w;++i)
    {
        if(stmp[i]<4)
        {
            ++stmp[i];
            if(Win())
            {ans.push_back(i);ansc.push_back(k);}
            --stmp[i];
        }
    }
}
int main()
{
    //freopen("data.txt","r",stdin);
    int T;
    char stmp[5];
    scanf("%d",&T);
    while(T--)
    {
       for(int i=0;i<N;++i)
       s[i]=c[i]=m[i]=p[i]=0;
       for(int i=1;i<=13;++i)
       {
           scanf("%s",stmp);
           int k=stmp[0]-'0';
           if(stmp[1]=='c')
           ++c[k];
           else if(stmp[1]=='p')
           ++p[k];
           else if(stmp[1]=='m')
           ++m[k];
           else if(stmp[1]=='s')
           ++s[k];
       }
       ans.clear();
       ansc.clear();
       Fans(m,'m');
       Fans(s,'s');
       Fans(p,'p');
       Fans(c,'c');
       if(ans.size()==0)
       printf("Nooten\n");
       else
       {
           printf("%d",ans.size());
           for(unsigned int i=0;i<ans.size();++i)
           {
               printf(" %d%c",ans[i],ansc[i]);
           }
           printf("\n");
       }
    }
    return 0;
}

转载于:https://www.cnblogs.com/liulangye/archive/2012/11/03/2752805.html

猜你喜欢

转载自blog.csdn.net/weixin_30511107/article/details/94791759
hdu