HDU 4431 Mahjong 简单的DFS

原创 2013年12月02日 10:47:02

题意:给出十三章牌,问有几种赢的方法。

思路:DFS枚举所有的情况,记得剪枝。

自己想得几组数据。

7
1s 1s 2s 2s 3s 3s 4s 4s 5s 5s 6s 6s 7s
3 1s 4s 7s
1s 1s 3s 3s 5s 5s 1p 1p 5m 5m 7c 7c 1c
1 1c
1s 2s 3s 2c 2c 2c 2p 3p 5m 6m 7m 1p 1p
2 1p 4p
1p 1p 2p 3p 4s 5s 6s 7c 7c 3s 3s 2m 2m
Nooten
1s 2s 3s 4s 5s 6s 7s 8s 9s 9s 9s 2c 3c
Nooten
1s 2s 3s 4s 5s 6s 7s 8s 9s 9s 9s 2c 2c
4 3s 6s 9s 2c
1s 9s 1m 9m 1p 9p 1c 2c 3c 4c 5c 6c 7c
13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <stack>

#define LL long long
#define EPS (1e-8)
#define Left true
#define Right false

using namespace std;

struct N
{
    int id,ty;
}s[15];

struct E
{
    int id;
    char ty;
}st[100000];

int mark[5][10];

bool dfs_con;

bool dfs(int t1,int t2,int eye,int r,int c)
{
    int i,j;

    if(dfs_con)
        return true;

    for(i = 1;i <= r; ++i)
    {
        for(j = 1;j < (i == r ? c : 9) ; ++j)
        {
            if(mark[i][j] != 0)
                return false;
        }
    }

    if(eye == 1 && mark[r][c] != 3 && mark[r][c] != 0 && ( (c == 9 && mark[r][c-1] == 0) || (c == 1 && mark[r][c+1] == 0) || (1 < c && c < 9 && mark[r][c+1] == 0 && mark[r][c-1] == 0)))
    {
        return false;
    }
    if(eye == 0 && mark[r][c] == 4 && mark[r][c] == 1 && ( (c == 9 && mark[r][c-1] == 0) || (c == 1 && mark[r][c+1] == 0) || (1 < c && c < 9 && mark[r][c+1] == 0 && mark[r][c-1] == 0)))
    {
        return false;
    }
    if(t1+t2 == 4 && eye)
    {
        dfs_con = true;
        return true;
    }

    for(i = r;i <= 4; ++i)
    {
        for(j = (i == r ? c : 1) ; j <= 9; ++j)
        {
            if(eye == 0)
            {
                if(mark[i][j] >= 2)
                {
                    mark[i][j] -= 2;
                    if(dfs(t1,t2,1,i,j) == true)
                        return true;
                    mark[i][j] += 2;
                }
            }
            if(mark[i][j] >= 3)
            {
                mark[i][j] -= 3;
                if(dfs(t1+1,t2,eye,i,j) == true)
                {
                    return true;
                }
                mark[i][j] += 3;
            }
            if(i != 4 && j <= 7 && mark[i][j] >= 1 && mark[i][j+1] >= 1 && mark[i][j+2] >= 1)
            {
                mark[i][j]--;
                mark[i][j+1]--;
                mark[i][j+2]--;
                if(dfs(t1,t2+1,eye,i,j) == true)
                {
                    return true;
                }
                mark[i][j]++;
                mark[i][j+1]++;
                mark[i][j+2]++;
            }
        }
    }
    return false;
}

bool Is_Win(N *p)
{
    int eye;
    int i,j;
    memset(mark,0,sizeof(mark));
    for(i = 1;i <= 14; ++i)
    {
        mark[p[i].ty][p[i].id]++;
    }

    eye = 0;

    for(i = 1;i <= 4; ++i)
    {
        for(j = 1;j <= 9; ++j)
        {
            if(mark[i][j] == 2)
            {
                eye++;
            }
            if(mark[i][j] >= 5)
                return false;
        }
    }

    if(eye == 7)
    {
        return true;
    }

    for(i = 1;i <= 3 && 1 <= mark[i][1] && 1 <= mark[i][9] ; ++i)
        ;

    if(i == 4)
    {
        for(i = 1;i <= 7 && 1 <= mark[4][i] ; ++i)
            ;
        if(i == 8)
        {

            for(i = 1;i <= 3 ; ++i)
            {
                if(2 == mark[i][1] || 2 == mark[i][9])
                    return true;
            }
            for(i = 1;i <= 7; ++i)
            {
                if(mark[4][i] == 2)
                    return true;
            }
        }
    }

    dfs_con = false;
    return dfs(0,0,0,1,1);
}

int main()
{
    int n,i;

    int top;

    scanf("%d",&n);
    char c;
    while(n--)
    {
        top = 0;
        E temp;
        for(i = 1;i <= 13; ++i)
        {
            scanf("%d%c",&s[i].id,&c);
            if(c == 'm')
            {
                s[i].ty = 1;
            }
            else if(c == 's')
            {
                s[i].ty = 2;
            }
            else if(c == 'p')
            {
                s[i].ty = 3;
            }
            else if(c == 'c')
            {
                s[i].ty = 4;
            }
        }

        for(i = 1;i <= 9; ++i)
        {
            s[14].id = i;
            s[14].ty = 1;
            if(Is_Win(s))
            {
                temp.id = i;
                temp.ty = 'm';
               st[top++] = temp;
            }
        }

        for(i = 1;i <= 9; ++i)
        {
            s[14].id = i;
            s[14].ty = 2;
            if(Is_Win(s))
            {
                temp.id = i;
                temp.ty = 's';
                st[top++] = temp;
            }
        }

        for(i = 1;i <= 9; ++i)
        {
            s[14].id = i;
            s[14].ty = 3;
            if(Is_Win(s))
            {
                temp.id = i;
                temp.ty = 'p';
                st[top++] = temp;
            }
        }

        for(i = 1;i <= 7; ++i)
        {
            s[14].id = i;
            s[14].ty = 4;
            if(Is_Win(s))
            {
                temp.id = i;
                temp.ty = 'c';
                st[top++] = temp;
            }
        }

        if(top == 0)
        {
            printf("Nooten\n");
        }
        else
        {
            printf("%d",top);
            for(i = 0;i < top; ++i)
            {
                printf(" %d%c",st[i].id,st[i].ty);
            }
            printf("\n");
        }
    }
    return 0;
}


相关文章推荐

hdu 4431 Mahjong(dfs+模拟)

前前后后提交了十几遍,终于A掉了。 在判断七小对的时候,一个牌出现四张不能当作两个对子。 然后就是各种细节。 #include #include #include #define N 35 ...

HDU 4431 Mahjong(天津赛区亚洲区) 模拟题,方法很重要

MahjongTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su...

HDU 4431 Mahjong

HDU 4431 Mahjong题目描述 Japanese Mahjong is a four-player game. The game needs four people to sit arou...

hdu 4431 Mahjong (模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4431 Mahjong Time Limit: 4000/2000 MS (Java/Other...

枚举+搜索 hdu-4431-Mahjong

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4431 题目大意: 给一副牌,求出所有能糊的牌。 解题思路: 枚举每一张牌,看能不能糊。 因为一共只...

HDU 4431 Mahjong (麻将、神坑模拟题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4431 题面: Mahjong Time Limit: 4000/2000 MS (J...

HDU_4431_Mahjong(模拟)

题意:打麻将。三种胡牌方法。题意应该都懂。 分析:模拟。枚举放的那张牌,然后分别用三种胡牌方法判断是否能胡牌。第一种方法是普通的胡牌,枚举每一对作为眼睛,然后判断剩余的牌是否满足;第二种是七对,直接...

hdu 4431 Mahjong,uva 11210 chinese Mahjong,麻将,超快的解法。。

这个代码在hdu可以进前五,运行时间是140ms(我贴的代码是156ms,不用cin cout 就可以140ms了好像) 题目就是我们熟悉的麻将,题目会给你13 张牌,你判他能不能胡,以及胡那些牌 o...

HDU 5379 Mahjong tree(dfs)——多校练习7

HDU 5379 Mahjong tree(dfs)——多校练习7

hdu 5379 Mahjong tree 2015多校联合训练赛#7 dfs

Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 4431 Mahjong 简单的DFS
举报原因:
原因补充:

(最多只允许输入30个字)