hdu 4431 Mahjong

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;

}

 

你可能感兴趣的:(HDU)