麻雀游戏

麻雀游戏(mahjong)

1s/512MB

【题目背景】

Yazid 是一名咸鱼,他最近沉迷上了日麻(日本麻将)这一游戏。

【题目描述】

麻将,起源于中国,是由中国汉族人发明的博弈游戏,娱乐用具,一般用骨头、竹  子或塑料制成小长方块,上面刻有花纹或字样,每副136 张。

和一般的麻将游戏一样,日麻中的牌也分为 5 类:

•   万:有数字 1 . . . 9 共 9 种,用m来记录。如:二万记为2m;二万四万五万记为245m

•  饼:有数字 1 . . . 9 共 9 种,用p来记录。(记录方法与万类似)

•  索:有数字 1 . . . 9 共 9 种,用s来记录。(记录方法与万、饼类似)

•  风牌:有东风E、南风S、西风W、北风N共 4 种。

•   元牌:有白板Wd、发财Gd、红中Rd共 3 种。

其中,万m、饼p、索s统称为数牌;风牌和元牌统称为字牌。每种牌最多有 4 张,也

就是说不可能存在第 5 张1pRd或其他任何牌。

每一位玩家每个时刻手上的牌称为手牌。我们可以用上述规则来表示一副手牌。在  本题中,我们保证给出的手牌表示按上述顺序排序。如123m234p456sESWNWdRd就是  合法的,而123p456m(万应在饼之前)、123m57m(所有万应一起描述)、123654s

(同种数牌的描述中数字应有序)、EEERd123456789m(数牌应在字牌之前)这样的都  是不合法的,在输入数据中不会出现这样的情况。

四位玩家围坐成一圈,轮流摸牌。大多数时间里,每位玩家的手牌数是 13 张。一

名玩家摸牌后,如果满足 13 张手牌加上这一张牌组成四面子加一对子的形式,那么你就可以将你的牌推倒,称为胡牌。

其中,对子表示两张相同的牌,而面子分为 3 类:

•  顺子:三张连续的数字牌。如:123p

•   刻子:三张完全相同的牌。如:WdWdWd555s等。

•   杠子:一种特殊的刻子,由四张相同的牌组成,本题不考虑。

同样,如果你已经听牌(差一张牌胡牌),那么在任一其他玩家打出你需要的那张牌时,你也可以推倒胡牌,称为荣和。

了解了规则后,Yazid 兴高采烈的开始了游戏。然而,Yazid 发现,很多时候他满足了胡牌的条件,却不能推倒胡牌。经过规则的查阅,Yazid 发现在日麻中胡牌必须要有一种叫做 ‘‘役’’的东西。

通过阅读新手教学,Yazid 了解到,在日麻中,最常见的三个役分别是:立直、断幺、役牌。 

•  立直:在门清状态下,如果你已经听牌,那么你可以丢出一根点棒宣告立直。这  时你就凭空多了一个叫做 ‘‘立直’’ 的役。

•  断幺:指胡牌的牌型中没有幺九牌和字牌。幺九牌指的是点数为1 或 9 的数字牌。

•  役牌:由自风、场风或元牌组成的刻子(或杠子)。所谓自风和场风,是在一局游戏中对一位玩家而言固定的两种风牌。

例如,222m333p66677778s这个牌型就有 ‘‘断幺’’ 这个役。(如果宣告过立直,那么又会多出 ‘‘立直’’ 这个役)

再例如,234m234p23444sRdRdRd这个牌型就有 ‘‘役牌中’’ 这个役。(同样地,如果宣告过立直,那么又会多出 ‘‘立直’’ 这个役)

当然啦,作为资深日麻玩家的 ww140142,他还知道上面这个牌型还有 ‘‘三色同顺’’

这个役。但由于 Yazid 太弱了,所以他根本不关注这些厉害的役。

对于役牌,需要特殊说明的是,自风和场风有时需要重复计算。例如在东场中,

Yazid 又恰好坐东家(即对 Yazid 来说自风、场风均为东风),那么东风的刻子(或杠子)就算作 2 组役牌,如222333444p99sEEE这个牌型就有 ‘‘自风东’’、‘‘场风东’’ 两个役。

由于 Yazid 太弱了,所以他根本没法宣告立直(因为他必须鸣牌才能听牌)。现在他摸上来一张牌后,发现自己可以胡牌了。但他不知道自己有哪些役。所以他找到了  你,请你帮他判断他的手牌是否断幺、是否有役牌。

针对熟悉日麻规则选手的提醒:本题不考虑七对子、国士无双等特殊的胡牌形式。

也保证给出的手牌张数均为14,也就是说不存在杠子。

【输入格式】

从文件 mahjong.in 中读入数据。

本题包含多组数据,第一行一个正整数 T 表示数据组数。接下来依次描述每组数据。对于每组数据:

第一行 2 个大写字母,分别依次表示自风和场风,符号与风牌符号一致。其中,场风只可能为东E、南S

第二行一个字符串描述手牌。保证符合题目描述中的规则,保证手牌数恰好为14, 保证该手牌由四面子加一对子组成。

【输出格式】

输出到文件 mahjong.out 中。

对于每组数据,输出一行 2 个用空格隔开的整数,其中第一个整数表示是否断幺

(断幺为 1,没有断幺为 0),第二个整数表示役牌的组数。

【样例 1 输入】

3

NE 

222m333p66677778s

WS 

234m234p23444sRdRdRd

EE

222333444p99sEEE

【样例 1 输出】

1 0

0 1

0 2

【样例 2】

见选手目录下的 mahjong/mahjong2.inmahjong/mahjong2.ans

【提示】

断幺和役牌似乎不能共存哦。

【子任务】

对于 30% 的数据,保证 T =1。

对于另外 10% 的数据,保证一定不存在字牌。对于另外 10% 的数据,保证一定不存在 ‘‘役牌’’。对于另外10% 的数据,保证一定存在字牌。

对于另外 10% 的数据,保证一定没有 ‘‘断幺’’。对于另外10% 的数据,保证T ≤ 10。

对于 100% 的数据,保证 T ≤ 104

题解:这题题目看起来很长,但比较简单。唯一要注意的是:不能将‘WWWd’判为三个‘W’。

Code:

var 
  t,l,i,k,ans1,ans2:longint;
  st:string;
  c1,c2:char;
  f:array[1..7]of string;
  s:array[1..7]of longint;
begin
  assign(input,'mahjong.in');reset(input);
  assign(output,'mahjong.out');rewrite(output);
  readln(t);
  f[1]:='Wd';f[2]:='Gd';f[3]:='Rd';
  f[4]:='E';f[5]:='S';f[6]:='W';f[7]:='N';
  for l:=1 to t do
  begin
    readln(c1,c2);
    readln(st);
    ans1:=0;ans2:=0;
    fillchar(s,sizeof(s),0);
    for i:=1 to 3 do
    begin
      k:=pos(f[i],st);
      while k<>0 do
      begin
        inc(s[i]);
        delete(st,k,2);
        k:=pos(f[i],st);
      end;
    end;
    for i:=4 to 7 do
    begin
      k:=pos(f[i],st);
      while k<>0 do
      begin
        inc(s[i]);
        delete(st,k,1);
        k:=pos(f[i],st);
      end;
    end;
    if (pos('1',st)=0)and(pos('9',st)=0)and
    (s[1]=0)and(s[2]=0)and(s[3]=0)and(s[4]=0)
    and(s[5]=0)and(s[6]=0)and(s[7]=0) then inc(ans1);
    for i:=1 to 3 do
      if s[i]>=3 then inc(ans2);
    for i:=4 to 7 do
    begin
      if (f[i]=c1)and(s[i]>=3) then inc(ans2);
      if (f[i]=c2)and(s[i]>=3) then inc(ans2);
    end;
    writeln(ans1,' ',ans2);
  end;
  close(input);close(output);
end.

你可能感兴趣的:(=====基础=====,#,模拟)