ZOJ3669:Japanese Mahjong I

本文深入探讨了游戏开发领域的核心技术,包括游戏引擎、图形渲染、3D空间视频等关键概念及应用,为游戏开发者提供深入的技术指导。

Mahjong is a game of skill, strategy and calculation and involves a certain degree of chance. In this problem, we concentrate on Japanese Mahjong, a variation of mahjong. For brief, all of the word mahjong mentioned following refer to Japanese Mahjong.

Japanese mahjong is usually played with 136 tiles, which can be organized into several categories:

  • Suited tiles. All suited tiles are of a rank and a suit.There are three suits of tiles, with ranks ranging from one to nine. There are four tiles of each rank and suit combination, thus there are 36 tiles in a suit, and 108 suited tiles in total.
    • The circle suit
    • The bamboo suit
    • The character suit
  • Honor tiles. Honor Tiles are tiles that do not have a rank or suit. They are divided into two categories. There are four types of Wind tiles and three types of Dragon tiles, with four of each type of honor tile. Thus, there are 16 wind tiles and 12 Dragon tiles for 28 honor tiles.
    • Wind tiles. The Wind tiles consist of four kinds of tile: EastSouthWest, and North.
    • Dragon tiles. The Dragon titles consist of three types of tile: RedGreenWhite.

winning hand consists of fourteen tiles, which is made of four melds (a specific pattern of three pieces) and the eyes (a pair of two identical pieces). The definition of melds and eyes is given as followed:

  • Melds are listed as followed:
    • Pong is a set of three identical tiles. You can form a pong with any tile. The tiles must be identical (you cannot mix suits). For example:
    • Kong is a set of four identical tiles, which is similar to Pong. For example:
    • Chow is a meld of three suited tiles in sequence. The meld must be in absolute numerical sequence. There is no skipping of numbers, nor does 9 loop around to 1. The sequence must be in the same suit. Honours cannot be used to make chows. For example:
  • Eyes, also known as a pair, are two identical tiles which are a component to the standard hand. For example:

When a hand is one tile short of winning, the hand is said to be a ready hand, or more figuratively, "on the pot". The player holding a ready hand is said to be waiting for certain tiles. Now, given thirteen tiles, can you answer how many types of tiles you are waiting for a winning hand? If the given hand were not a ready hand, output an integer zero instead.

Input

There are multiple cases. Each case consists of 26 characters in one line, describing thirteen tiles. The manner for describing each type of tile is:

  • Two characters stand for one tile.
  • For Suited tiles, the first is a integer ranged from one to nine, the tile's rank, and the second is a character: 'p' for the circle suit, 's' for the bamboo suit, and 'm' for the character suit.
  • For Honor tiles, the first is a integer: from one to seven stands for EastSouthWestNorthWhiteGreen, and Red respectively. The second one is always 'z'.
We promise that the input is a legal hand, which means there isn't another type of tiles described above or there are more than four same tiles.
Output

For each case, first output the number of types of tiles you are waiting for in one line. Then output each type of tile you are waiting for in the manner described above. output them in this fixed order: 'm', 'p', 's', 'z', and for each suit, smaller rank first (Honor tiles is similar to suited tiles, only using the integer standing for in above manner instead of suited rank).

Sample Input
1s1s1s2p3p4p6m7m8m1z1z1z2z
1s1s1s2p3p4p6m7m8m1z1z1z9m
1s1s1s2p3p4p6m7m8m1z1z1z1z
1s2s3s1s2s3s2s3s7s8s9s6z6z
Sample Output
1 2z
2 6m9m
0
3 1s4s6z
Hint
  • The hand in the first picture is not a winning hand indeed, because there are fifteen tiles. If 1m or 9m is droped, it will be a winning hand.
  • Note that the input tiles is not ensured in the order of output.


题意

按一题目的要求输出摸到那些牌能胡牌


#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

struct node
{
    int num;
    char kind;
} s[100000];

char str[100];
int a[4][15];
int ta[4][15];
int len,cnt;

int find(int num)//找出4个三个一组的
{
    int i,j;
    if(num == 0) return 1;
    for(i = 0; i<4; i++)//找出三个一样的
    {
        for(j = 1; j<=9; j++)
        {
            if(a[i][j]<3) continue;
            a[i][j]-=3;
            if(find(num-1))
                return 1;
            a[i][j]+=3;
        }
    }
    for(i = 0; i<3; i++)//找出一句话
    {
        for(j = 1; j<=7; j++)
        {
            if(a[i][j] && a[i][j+1] && a[i][j+2])
            {
                a[i][j]--,a[i][j+1]--,a[i][j+2]--;
                if(find(num-1))
                    return 1;
                a[i][j]++,a[i][j+1]++,a[i][j+2]++;
            }
        }
    }
    return 0;
}

int solve()
{
    int i,j;
    for(i = 0; i<4; i++)
    {
        for(j = 1; j<=9; j++)
        {
            if(a[i][j]<2) continue;
            if(i==3 && j<=7)
            {
                a[i][j]-=2;
                if(find(4)) return 1;
                a[i][j]+=2;
            }
            else
            {
                a[i][j]-=2;
                if(find(4)) return 1;
                a[i][j]+=2;
            }
        }
    }
    return 0;
}

int main()
{
    int i,j,k;
    while(~scanf("%s",str))
    {
        cnt = 0;
        memset(a,0,sizeof(a));
        for(i = 0; i<26; i+=2)
        {
            if(str[i+1] == 'm')
                a[0][str[i]-'0']++;
            else if(str[i+1] == 'p')
                a[1][str[i]-'0']++;
            else if(str[i+1] == 's')
                a[2][str[i]-'0']++;
            else if(str[i+1] == 'z')
                a[3][str[i]-'0']++;
        }
        char kind[5]="mpsz";
        for(i = 1; i<=27+7; i++)//枚举所有摸到的牌
        {
            int id = (i-1)/9;
            int no = i%9;
            if(no == 0)
                no = 9;
            memcpy(ta,a,sizeof(a));
            if(id<4 && a[id][no]<4)//只有小于四张才能摸到
                a[id][no]++;
            else
                continue;
            if(solve())
            {
                s[cnt].num = no;
                s[cnt].kind = kind[id];
                cnt++;
            }
            memcpy(a,ta,sizeof(ta));
        }
        if(cnt == 0)
        {
            printf("0\n");
            continue;
        }
        printf("%d ",cnt);
        for(i = 0; i<cnt; i++)
            printf("%d%c",s[i].num,s[i].kind);
        printf("\n");

    }

    return 0;
}


今天小编为大家介绍一款简单好用的极速双核浏览器软件——jizz浏览器软件。软件基于谷歌Chrome内核同时兼容IE内核,兼容所有Chrome扩展,更快速、更安全、更稳定性。软件界面美观简洁、使用方便,速度快,质量高,对于用户来说是一款很不错的软件,小编这里推荐大家使用这款软件! jizz浏览器软件特色 1.双核智能云切换 提供IE内核的兼容模式,双核智能云切换: 通常情况下,使用极速模式会获得更好的浏览体验,但是国内一些网站(例如网银)不支持Chrome内核,此时jizz提供了兼容模式。根据不同的网站智能选择模式,不建议手动切换,在遇到特殊情况时可以手动切换。 2.小号标签 小号标签,游戏、社区、论坛帐号多开更方便: 无论是玩游戏、逛社区、混贴吧、泡论坛、多开QQ空间,都常常需要用到小号,俗称“马甲”,小号标签功能使我们可以在一个浏览器窗口里同时登录多个小号而不串号。 3.鼠标手势 滑鼠在手,一划就走: 按住右键滑动鼠标就能轻松执行各种命令,默认命令经过了精心的设计,还支持自定义手势命令,可以按照自己习惯去设置。例如,您可以按住右键划出“向上再向左”的手势,就切换到前一个标签,还可以试试“向下再向右”的手势关闭当前标签。 4.贴心导航 精心设计,用心甄选: 新标签页中最常访问会根据您的使用习惯,筛选出几十个网站并自动排序,方便那些懒得加收藏夹的人。影视导航为您推荐最新最热门的电影电视剧,片源都是经过验证的,点进去就可以看了。 jizz浏览器软件截图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值