POJ 2024 Know When to Hold 'em

模拟

刚开始题目看错了,原来后面两个 hole cards 是不能用的……英语不太好。然后我就没有在训练规定时间内干掉这个题了。

做法就是暴力选牌,找到最大的手牌,如果有多种答案就枚举每一张牌,如果在每一种方案里它都出现那它就一定在答案里,否则把它的花色改成*就好了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define pii pair<int,int>
using namespace std;

int decode(char c)
{
    if(c == 'c') return 1;
    if(c == 'd') return 2;
    if(c == 'h') return 3;
    if(c == 's') return 4;
    if('2' <= c && c <= '9') return c - '0';
    if(c == 'A') return 14;
    if(c == 'T') return 10;
    if(c == 'J') return 11;
    if(c == 'Q') return 12;
    if(c == 'K') return 13;
    return 2333;
}

struct poker
{
    pii a[5];
    int v1, v2;
    bool operator == (poker that)
    {
        return v1 == that.v1 && v2 == that.v2;
    }
    bool operator < (poker that)
    {
        return v1 == that.v1 ? v2 < that.v2 : v1 < that.v1;
    }
}cur, ans[2333]; int anscnt;

pii hand[7], a[5];
char s[2];
bool vis[55][10];

void judge()
{
    memcpy(a, cur.a, sizeof a); sort(a, a+5);

    int flush = 1, straight = 0, four = 0, three = 0;
    for(int i = 1; i < 5; i++) if(a[i].second != a[i-1].second) flush = 0;
    if(a[0].first + 1 == a[1].first && a[1].first + 1 == a[2].first && a[2].first + 1 == a[3].first && a[3].first + 1 == a[4].first) straight = 1;
    if(a[4].first == 14 && a[0].first == 2 && a[1].first == 3 && a[2].first == 4 && a[3].first == 5) straight = 1;
    if(a[0].first == a[1].first && a[1].first == a[2].first && a[2].first == a[3].first) four = 1;
    if(a[1].first == a[2].first && a[2].first == a[3].first && a[3].first == a[4].first) four = 2;
    if(a[0].first == a[1].first && a[1].first == a[2].first) three = 1;
    if(a[1].first == a[2].first && a[2].first == a[3].first) three = 2;
    if(a[2].first == a[3].first && a[3].first == a[4].first) three = 3;

    if(flush && straight && a[4].first == 14 && a[0].first == 10) cur.v1 = 7, cur.v2 = 2333;
    else if(flush && straight)
    {
        cur.v1 = 6;
        if(a[4].first == 14) cur.v2 = a[3].first;
        else cur.v2 = a[4].first;
    }
    else if(four)
    {
        cur.v1 = 5;
        if(four == 1) cur.v2 = a[0].first * 20 + a[4].first;
        else cur.v2 = a[4].first * 20 + a[0].first;
    }
    else if((three == 3 && a[0].first == a[1].first) || (three == 1 && a[3].first == a[4].first))
    {
        cur.v1 = 4;
        if(three == 1) cur.v2 = a[0].first * 20 + a[4].first;
        else if(three == 3) cur.v2 = a[4].first * 20 + a[0].first;
    }
    else if(flush)
    {
        cur.v1 = 3;
        cur.v2 = 0;
        for(int i = 4; ~i; i--) cur.v2 = cur.v2 * 20 + a[i].first;
    }
    else if(straight)
    {
        cur.v1 = 2;
        if(a[4].first == 14 && a[3].first == 5) cur.v2 = 5;
        else cur.v2 = a[4].first;
    }
    else if(three)
    {
        cur.v1 = 1;
        if(three == 1) cur.v2 = a[2].first * 20 * 20 + a[4].first * 20 + a[3].first;
        if(three == 2) cur.v2 = a[2].first * 20 * 20 + a[4].first * 20 + a[0].first;
        if(three == 3) cur.v2 = a[2].first * 20 * 20 + a[1].first * 20 + a[0].first;
    }
    else cur.v1 = 0;


}

void dfs(int x, int cnt)
{
    if(cnt == 5)
    {
        judge();

        if(!anscnt)
        {
            ans[anscnt = 1] = cur;
        }
        else if(cur == ans[1])
        {
            ans[++anscnt] = cur;
        }
        else if(ans[1] < cur)
        {
            ans[anscnt = 1] = cur;
        }

        return;
    }
    if(x == 7) return;
    dfs(x+1, cnt);
    cur.a[cnt] = hand[x];
    dfs(x+1, cnt+1);
}

void out(poker p)
{
    sort(p.a, p.a+5);
    for(int i = 4; ~i; i--) 
    {
        printf("%c%c ","0023456789TJQKA"[p.a[i].first],"*cdhs"[p.a[i].second]);
    }
}

int main()
{
    int T; scanf("%d",&T);
    for(;T--;)
    {
        for(int i = 0; i <= 14; i++) for(int j = 0; j <= 4; j++) vis[i][j] = 0;
        for (int i = 0; i < 7; i++)
        {
            scanf("%s",s);
            hand[i].first = decode(s[0]);
            hand[i].second = decode(s[1]);
            vis[hand[i].first][hand[i].second] = 1;
        }

        anscnt = 0;
        for(int i = 2; i <= 14; i++) 
            for(int j = 1; j <= 4; j++) if(!vis[i][j])
            {
                vis[i][j] = 1;
                hand[5] = make_pair(i, j);
                for(int ii = i; ii <= 14; ii++)
                    for(int jj = 1; jj <= 4; jj++) if(!vis[ii][jj])
                    {
                        hand[6] = make_pair(ii, jj);
                        dfs(0,0);
                    }
                vis[i][j] = 0;
            }


        for(int i = 0; i < 5; i++)
        {
            bool all = 1;
            for(int j = 2; j <= anscnt; j++)
            {
                bool in = 0;
                for(int k = 0; k < 5; k++)
                    if(ans[1].a[i] == ans[j].a[k]) in = 1;
                if(!in) all = 0;
            }
            if(!all) ans[1].a[i].second = 0;
        }

        out(ans[1]);

        if(ans[1].v1 == 7) 
        {
            puts("ROYAL FLUSH");
        }
        if(ans[1].v1 == 6) 
        {
            puts("STRAIGHT FLUSH");
        }
        if(ans[1].v1 == 5) 
        {
            puts("FOUR OF A KIND");
        }
        if(ans[1].v1 == 4) 
        {
            puts("FULL HOUSE");
        }
        if(ans[1].v1 == 3) 
        {
            puts("FLUSH");
        }
        if(ans[1].v1 == 2) 
        {
            puts("STRAIGHT");
        }
        if(ans[1].v1 == 1) 
        {
            puts("THREE OF A KIND");
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值