HDU 4930 Fighting the Landlords 斗地主模拟

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4930
题意:虽然题目很长,但是其实就是一直在介绍我们很熟悉的斗地主规则。要求这一轮里是否A出牌后B没有牌可以压过A。
解题思路:这道题尤其要注意出牌的先后性,先处理先手一方的情况,因为它是先出牌的一方。如果先手(A)有王炸的优先级是最高的,最先处理这种情况,直接输出Yes。然后处理先手可以一次性打完手里的牌的情况,这种情况也是不用考虑后手(B)的情况直接输出Yes即可。
然后考虑其他的情况,即先手无法直接秒杀后手的情况,此时要具体考虑后手的牌的情况。这时后手里是否有王炸的优先级是最高的,如果有王炸直接输出No即可。然后我们处理B中有炸弹的情况,因为炸弹可以攻击任意的除了王炸外的出牌,比较AB中炸弹的大小(如果存在),如果B的炸弹大于A或者A没有炸弹,则B此轮压过A,输出No。如果B没有炸弹,进行下面的步骤:再接下来细分各种出牌的组合可能性,对应地一一比较大小,如果A有任一出牌组合大于B,则输出Yes,然后结束算法。因为A是先手,它有出牌的主动权,所以只要有任意一种出牌方式B没法接,即可打出这种方式,那么B一定没有牌可以接,故输出Yes。
AC代码:

/*****************************************
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'   |     |//  `.
            /   |||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\  -  /// |   |
           |  _|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `-  `.;`\ _ /`;.`/ - ` : | |
     \  \ `-.    _ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         佛祖保佑       永无BUG
*****************************************/
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
map<char,int> m;
map<char,int> cnt1;
map<char,int> cnt2;
int main()
{
    m['3'] = 1;
    m['4'] = 2;
    m['5'] = 3;
    m['6'] = 4;
    m['7'] = 5;
    m['8'] = 6;
    m['9'] = 7;
    m['T'] = 8;
    m['J'] = 9;
    m['Q'] = 10;
    m['K'] = 11;
    m['A'] = 12;
    m['2'] = 13;
    m['X'] = 14;
    m['Y'] = 15;
    int t;
    scanf("%d", &t);
    char str1[20];
    char str2[20];
    while (t--)
    {
        cnt1.clear();
        cnt2.clear();
        scanf("%s %s", str1, str2);
        int len1 = strlen(str1);
        int len2 = strlen(str2);
        for (int i = 0; i < len1; i++) cnt1[str1[i]]++;
        for (int i = 0; i < len2; i++) cnt2[str2[i]]++;
        if (cnt1['X'] && cnt1['Y'])
        {
            puts("Yes");
            continue;
        }
        //直接能打完获胜
        //1.单个
        if (len1 == 1)
        {
            puts("Yes");
            continue;
        }
        //2.对子
        if (len1 == 2 && str1[0] == str1[1])
        {
            puts("Yes");
            continue;
        }
        //3.3连
        if (len1 == 3 && cnt1[str1[0]] == 3)
        {
            puts("Yes");
            continue;
        }
        //4.三带一
        if (len1 == 4)
        {
            bool ok = false;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] >= 3)
                {
                    ok = true;
                    break;
                }
            }
            if (ok)
            {
                puts("Yes");
                continue;
            }
        }
        //5.三带二同
        if (len1 == 5)
        {
            bool ok = false;
            for (int i = 0; i < 5 && !ok; i++)
            {
                for (int j = 0; j < 5 && !ok; j++)
                {
                    if (i == j) continue;
                    if (str1[i] != str1[j] && ((cnt1[str1[i]] == 2 && cnt1[str1[j]] == 3) || (cnt1[str1[i]] == 3 && cnt1[str1[j]] == 2)))
                    {
                        ok = true;
                    }
                }
            }
            if (ok)
            {
                puts("Yes");
                continue;
            }
        }
        //6.四带二可不同
        if (len1 == 6)
        {
            bool ok = false;
            for (int i = 0; i < 6; i++)
            {
                if (cnt1[str1[i]] == 4)
                {
                    ok = true;
                    break;
                }
            }
            if (ok)
            {
                puts("Yes");
                continue;
            }
        }
        //7.王炸(已最先处理)
        //8.炸弹(包在4中了)
        //---------华丽丽的分割线---------//
        int r1 = -1;
        int r2 = -1;
        if (cnt2['X'] && cnt2['Y'])
        {
            puts("No");
            continue;
        }
        for (int i = 0; i < len2; i++)
        {
            if (cnt2[str2[i]] == 4)
            {
                r2 = max(r2,m[str2[i]]);
            }
        }
        if (r2 != -1)
        {
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] == 4)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 < r2)//r1 == -1 || r1 < r2
            {
                puts("No");
                continue;
            }
        }
        //1.单个
        r1 = -1;
        r2 = -1;
        for (int i = 0; i < len1; i++) r1 = max(r1,m[str1[i]]);
        for (int i = 0; i < len2; i++) r2 = max(r2,m[str2[i]]);
        if (r1 > r2)
        {
            puts("Yes");
            continue;
        }
        //2.对子
        if (len1 >= 2)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] >= 2)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 != -1 && len2 < 2)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                if (cnt2[str2[i]] >= 2)
                {
                    r2 = max(r2,m[str2[i]]);
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        //3.3连
        if (len1 >= 3)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] >= 3)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 != -1 && len2 < 3)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                if (cnt2[str2[i]] >= 3)
                {
                    r2 = max(r2,m[str2[i]]);
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        //4.三带一
        if (len1 >= 4)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] == 3)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 != -1 && len2 < 4)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                if (cnt2[str2[i]] == 3)
                {
                    r2 = max(r2,m[str2[i]]);
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        //5.三带二同
        if (len1 >= 5)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                for (int j = 0; j < len1; j++)
                {
                    if (i == j) continue;
                    if (str1[i] != str1[j])
                    {
                        if (cnt1[str1[i]] == 3 && cnt1[str1[j]] == 2)
                        {
                            r1 = max(r1,m[str1[i]]);
                        }
                        if (cnt1[str1[i]] == 2 && cnt1[str1[j]] == 3)
                        {
                            r1 = max(r1,m[str1[j]]);
                        }
                    }
                }
            }
            if (r1 != -1 && len2 < 5)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                for (int j = 0; j < len2; j++)
                {
                    if (i == j) continue;
                    if (str2[i] != str2[j])
                    {
                        if (cnt2[str2[i]] == 3 && cnt2[str2[j]] == 2)
                        {
                            r2 = max(r2,m[str2[i]]);
                        }
                        if (cnt2[str2[i]] == 2 && cnt2[str2[j]] == 3)
                        {
                            r2 = max(r2,m[str2[j]]);
                        }
                    }
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        //6.四带二可不同
        if (len1 >= 6)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] == 4)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 != -1 && len2 < 6)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                if (cnt2[str2[i]] == 4)
                {
                    r2 = max(r2,m[str2[i]]);
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        //7.王炸
        //8.炸弹
        if (len1 >= 4)
        {
            r1 = -1;
            r2 = -1;
            for (int i = 0; i < len1; i++)
            {
                if (cnt1[str1[i]] == 4)
                {
                    r1 = max(r1,m[str1[i]]);
                }
            }
            if (r1 != -1 && len2 < 4)
            {
                puts("Yes");
                continue;
            }
            for (int i = 0; i < len2; i++)
            {
                if (cnt2[str2[i]] == 4)
                {
                    r2 = max(r2,m[str2[i]]);
                }
            }
            if (r1 > r2)
            {
                puts("Yes");
                continue;
            }
        }
        puts("No");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值