zoukankan      html  css  js  c++  java
  • [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
    题解:dp
    f[i][j][k][1,0]表示第i个数,选j个,第i-1个数选k个有无对子
    1.打出一个对子f[i][j][k][1]|=f[i][j-2][k][0]
    2.打出一句话(3个)f[i][j][k][]|=f[i][j-3][k][]
    3.打出4个f[i][j][k][]|=f[i][j-4][k][]
    4.最复杂的地方,还有玄学
    f[i][j][k][]|=f[i-1][k-j][a[i-2]-j][]
    不知为何这里条件不能打i>=2,打上就错,不打就对,应该是某种边界转移
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int f[101][101][101][2],a[101];
     7 int main()
     8 {int T,i,j,k;
     9      cin>>T;
    10      while (T--)
    11      {
    12          memset(f,0,sizeof(f));
    13          for (i=1;i<=3;i++)
    14          {
    15              scanf("%d",&a[i]);
    16         }
    17         f[0][0][0][0]=1;
    18           for (i=1;i<=100;i++)
    19           {
    20               for (j=0;j<=a[i-1];j++)
    21               {
    22                   for (k=0;k<=a[i];k++)
    23                   {
    24                       if (k>1) 
    25                       f[i][k][j][1]|=f[i][k-2][j][0];
    26                       if (k>2)
    27                       f[i][k][j][0]|=f[i][k-3][j][0],f[i][k][j][1]|=f[i][k-3][j][1];
    28                       if (k>3)
    29                       f[i][k][j][0]|=f[i][k-4][j][0],f[i][k][j][1]|=f[i][k-4][j][1];
    30                       if (j>=k&&a[i-2]>=k)
    31                     {
    32                      f[i][k][j][0]|=f[i-1][j-k][a[i-2]-k][0];
    33                        f[i][k][j][1]|=f[i-1][j-k][a[i-2]-k][1];
    34                       }
    35                 }
    36             }
    37           }
    38          if (f[100][a[100]][a[99]][1]) cout<<"Yes
    ";
    39          else cout<<"No
    ";
    40      }
    41 }
    
    
    
    
    
  • 相关阅读:
    diary and html 文本颜色编辑,行距和其它编辑总汇
    bash coding to changeNames
    virtualbox ubuntu 网络连接 以及 连接 secureCRT
    linux 学习6 软件包安装
    linux 学习8 权限管理
    vim 使用2 转载 为了打开方便
    ubuntu
    linux 学习15 16 启动管理,备份和恢复
    linux 学习 14 日志管理
    linux 学习 13 系统管理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7258518.html
Copyright © 2011-2022 走看看