[ZJOI2006]超级麻将

[ZJOI2006]超级麻将

题目描述

很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则:

普通麻将有砣、索、万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9索,1万~9万各有4张,所以共36*3=108张牌。胡牌时每人有14张牌,其中只要某人手里有若干句话(就是同种类型的牌连续三张或同种牌三张),另外再加上一对,即可胡牌。当然如果全是对,叫七小对,也可以胡牌。下图是连三张示例。

要判断某人是否胡牌,显然一个弱智的算法就行了,某中学信息学小组超级麻将迷想了想,决定将普通麻将改造成超级麻将。

所谓超级麻将没有了砣、索、万的区分,每种牌上的数字可以是1~100,而每种数字的牌各有100张。另外特别自由的是,玩牌的人手里想拿多少张牌都可以,好刺激哦!

刺激归刺激,但是拿多了怎么胡牌呢?

超级麻将规定只要一个人手里拿的牌是若干句话(三个连续数字的牌各一张组成一句话,三张或者四张同样数字的牌也算一句话),再加上一对相同的牌,就算胡了。

作为信息学竞赛选手的你,麻烦你给这位超级麻将迷编个程序,判断能否胡牌。

输入输出格式

输入格式:

 

输入文件第一行一个整数N(N<=100),表示玩了N次超级麻将。

接下来N行,每行100个数a1..a100,描述每次玩牌手中各种牌的数量。ai表示数字为i的牌有ai张。(0<=ai<=100)

 

输出格式:

 

输出N行,若胡了则输出Yes,否则输出No,注意区分Yes,No的大小写!

 

输入输出样例

输入样例#1:
3
2 4 0 0 0 0 0 …… 0(一共98个0)
2 4 2 0 0 0 0 …… 0(一共97个0)
2 3 2 0 0 0 0 …… 0(一共97个0)
输出样例#1:
Yes
Yes
No

题解:

推荐一个大神的博客

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#define RE register
using namespace std;
int n,a[102];
bool f[102][101][101][2];
int gi()
{
    int ans=0,f=1;
    char i=getchar();
    while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
    while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
    return ans*f;
}
int main()
{
    n=gi();
    while(n--)
    {
        memset(f,0,sizeof(f));
        for(RE int i=2;i<=101;i++)
        a[i]=gi();
        f[1][0][0][0]=1;
        for(RE int i=2;i<=101;i++)
        {
            for(RE int j=0;j<=a[i-1];j++)
            {
                for(RE int k=0;k<=a[i];k++)
                {
                    if(k>1)f[i][j][k][1]|=f[i][j][k-2][0];
                    if(k>2)f[i][j][k][0]|=f[i][j][k-3][0],f[i][j][k][1]|=f[i][j][k-3][1];
                    if(k>3)f[i][j][k][0]|=f[i][j][k-4][0],f[i][j][k][1]|=f[i][j][k-4][1];
                    if(a[i-2]>=k&&j>=k)f[i][j][k][0]|=f[i-1][a[i-2]-k][j-k][0],f[i][j][k][1]|=f[i-1][a[i-2]-k][j-k][1];
                }
            }
        }
        if(f[101][a[100]][a[101]][1])printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/huangdalaofighting/p/7265212.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值