BZOJ1028【JSOI2007】麻将

3 篇文章 0 订阅
2 篇文章 0 订阅

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1028


【分析】

枚举加上的那张等待牌。

统计出每个序数相同的牌的数量,然后按序数从小到大分牌。对于序数相同的牌,先考虑刻子(3个相同),然后剩下的牌按顺子分掉,分不掉就说明当前牌不是听牌。

简略的证明:3个顺子即3个刻子,所以优先考虑刻子;如果前面的牌都分完了,当前要分的同序数的牌还剩1或2个,那么必须弄成顺子分掉,分不掉显然就不是听牌了。


【代码】

#include <cstdio>
using namespace std;
const int maxn=410;
 
int a[maxn];
int t[maxn];
int n,m,x;
bool Hula;
 
bool Check()
{
    for (int k=1;k<=n;k++)
    {
        bool Pass=true;
        for (int i=1;i<=n;i++) t[i]=a[i];
        t[k]-=2;
        for (int i=1;i<=n;i++)
        {
            t[i]%=3;
            if (t[i+1]<t[i] || t[i+2]<t[i]) {Pass=false;break;}
            t[i+1]-=t[i],t[i+2]-=t[i];
            t[i]=0;
        }
        if (Pass) return true;
    }
    return false;
}
 
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=0;i<3*m+1;i++) scanf("%d",&x),a[x]++;
    Hula=false;
    for (int i=1;i<=n;i++)
    {
        a[i]++;
        if (Check())
        {
            if (Hula) printf(" ");
            Hula=true;
            printf("%d",i);
        }
        a[i]--;
    }
    if (!Hula) printf("NO");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值