UVALing 7293 Poker

Description

Poker is a family of gambling card games involving betting and individual play, whereby the winner is determined by the ranks and combinations of players' cards, some of which remain hidden until the end of the game.

Each card has a suit (Club, Diamond, Heart, Spade) and a rank. The ranks are, from lowest (least valuable) to highest (most valuable): ace (low), 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king, ace (high). Although only one ace card exists within each suit, and it is usually ranked as the highest card, under some circumstances the ace card will be treated as the lowest. The suit itself has no bearing on the worth of the card and is only used to determine which category a particular hand belongs to.

Poker hands are made of combinations of 2 to 5 cards in the hand. Cards that are not used in the combination are called kicker cards and can be used to break ties if needed.

The ranking of poker hands (best to worst) is as follows:

A Royal Flush is a hand that includes a 10, Jack, Queen, King, and Ace all of the same suit. If both hands have a Royal Flush, the hands tie.

A Straight Flush is a hand where the ranks of the cards are sequential and they all share the same suit. For example, a hand that has the 5, 6, 7, 8, and 9 of Clubs is a Straight Flush. An Ace can be either low (come before a 2) or high (come after a King). When comparing Straight Flushes, the straight with the highest ranked card wins. If the hands have the same highest ranked card, the hands tie.

A Four of a Kind is a hand that contains four cards of the same rank. For example, a hand that has the 2 of Clubs, 2 of Hearts, 2 of Diamonds, 2 of Spades, and any other card is a Four of a Kind. When comparing Four of a Kinds, the hand with the set of four cards with the highest rank wins.

A Full House is a hand that contains three cards of one rank and two cards of another rank. For example, a hand that has the 2 of Clubs, 2 of Hearts, 2 of Diamonds, 3 of Clubs, and 3 of Hearts is a Full House of 2s over 3s. When comparing Full Houses, the hand with the set of three cards with the highest rank wins.

A Flush is a hand of five cards that all share the same suit. For example, a hand that has the Ace of Spades, 3 of Spades, 7 of Spades, 10 of Spades, and King of Spades is a Flush. When comparing Flushes, the hand with the highest ranked card wins. If both hands have the same high card, compare the next highest card and repeat until a winner is found. If both hands have the same five ranks, the hands tie.

A Straight is a hand where the ranks of the cards are sequential. For example, a hand that has the 5 of Clubs, 6 of Hearts, 7 of Spades, 8 of Diamonds, and 9 of Clubs is a Straight. Like a Straight Flush, an Ace can be either high or low. When comparing Straights, the straight with the highest ranked card wins. If the hands have the same highest ranked card, the hands tie.

A Three of a Kind is a hand that has three cards of the same rank. For example, a hand that has the 2 of Clubs, 2 of Hearts, 2 of Diamonds, 3 of Clubs, and 4 of Clubs is a Three of a Kind of 2s. When comparing Three of a Kinds, the hand with the highest ranking set wins.

A Two Pair is a hand that has two sets of two cards of the same rank. For example, a hand that has the 2 of Clubs, 2 of Hearts, 3 of Clubs, 3 of Hearts, and the 4 of Clubs is a Two Pair. When comparing Two Pairs, the hand that has the highest ranking set wins. If both hands have the same highest ranking set, the hand with the second highest ranking set wins. If those sets have the same rank, the hand with the highest ranking kicker card wins. If the kicker cards have the same rank, the hands tie.

A One Pair is a hand that has one set of two cards of the same rank. For example, a hand that has the 2 of Clubs, 2 of Hearts, 3 of Clubs, 4 of Clubs, and 5 of Clubs is a One Pair. When comparing One Pairs, the hand with the highest rank set wins. If both hands have the same highest ranking set, then the hand with the highest kicker card is the winner. If both hands have the same high kicker card, compare the next highest kicker card and repeat until a winner is found. If both hands have the same kicker cards, the hands tie.

If neither hand has a special combination, the hand with the card with the highest rank wins. If both hands have the same high card, compare the next highest card and repeat until a winner is found. If both hands have the same five cards, ignoring suits, the hands tie.

Input

Input consists of a number of rounds to score, then two hands for each round.

The first line contains an integer W (1 <= W <= 200) indicating the number of rounds to score.

After the first line, there will be W pairs of lines of strings that describe a poker hand. The strings will be 5 rank and suit combinations separated by spaces. Single digit ranks (2 through 9) are represented by that number; Ten, Jack, Queen, King, and Ace are each represented by the (capitalized) first letter of the word. The suit is also represented by the (capitalized) first letter of its name. For example, "2C 4D 8H TD KS" is the hand that has the 2 of Clubs, 4 of Diamonds, 8 of Hearts, 10 of Diamonds, and King of Spades. Within each round, there will be no duplicate cards.

Output

For each pair of hands, output a single line containing the hand that wins the poker round or the string Tie if the hands tie. The hand should be displayed the same as it was given in the input file.

Sample Input

5
TC JC QC KC AC
9D TD JD QD KD
2C 2D 2S 3S 3D
TC JD QH KS AS
2D 4S 6H TS AS
8S 8D 3H KS AH
2S JS QS KS AH
3S JH QD KH AS
2S 2H AS AH KD
2D 3C AD AC KC

Sample Output

TC JC QC KC AC
2C 2D 2S 3S 3D
8S 8D 3H KS AH
3S JH QD KH AS
2S 2H AS AH KD

题意&思路

对于一个英语不好的人,这题实在是非常不友好。但是如果会玩扑克还会好懂点。

简单来说就是一副扑克发出两份牌,每份五张。给你每张牌的点数和花色。其中1为A,10为T,判断哪份能赢,然后输出。

一份牌共存在以下十种情况(优先度从高到低排列为:(优先度低的默认不构成上面的的情况

皇家同花顺 : 同花顺并且五张牌为T,J,Q,K,A。

同花顺:花色相同并且是顺子。

四同:四张点数一致的牌+另外任意一张。

三带一对:三同的基础上剩下两字点数也一致。

同花:五张的花色一致。

顺子:五张牌是连续的,其中A(1)比较特殊,可以构成A,2,3,4,5和T,J,Q,K,A。

三同:三张点数一致的剩下的两张点数互不相同。

两对:两个对子+任意一张牌。

一对:两张点数一致的,剩下的牌点数互不相同。

单张:不构成以上的任意一种情况的情况。

比较方式:优先判定优先度高的能赢,优先度一致时按照张数最多的点数大小依次往后比较。

其实题很简单,但是代码可能是因为个人比较菜的原因写的十分复杂(23333333

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>

using namespace std;

const int MAXN = 1e4+10;

struct Poker
{
    int a[5];    //点数(用于后面的排序
    int b[5];    //花色
    char c[5][3];//点数&花色(用于输出结果
    int d[5];    //将点数优先按照出现的次数从大到小排序
    int cnt;     //有几种点数
    int level;   //优先度
}s[2];

struct Card
{
    int a;
    int x;
}card[5];

bool cmp(Card a,Card b)
{
    if(a.x == b.x){
        return a.a>b.a;
    }
    return a.x>b.x;
}

int f(int x)//计算优先度并将点数按比较的优先级排好
{
    int a[5],b[5];
    for(int i=0;i<5;i++){
        a[i] = s[x].a[i];
        b[i] = s[x].b[i];
    }
    for(int i=0;i<4;i++){//写的时候比较乱并且觉得花色要跟着点数后来发现其实没必要可以直接sort(a,a+5);
        int k=i;
        for(int j=i+1;j<5;j++){
            if(a[j]<a[k]){
                k=j;
            }
        }
        int t=a[k];a[k]=a[i];a[i]=t;
        t=b[k];b[k]=b[i];b[i]=t;
    }

    map<int,int>m;//统计出现过几种牌
    for(int i=0;i<5;i++){
        m[a[i]]++;
    }
    int cnt = 0;
    map<int,int>::iterator it;
    for(it = m.begin();it != m.end();it++){
        cnt++;
    }
    s[x].cnt = cnt;

    int num = 0;//将点数优先按照出现的次数排好
    card[num].a = a[0];
    card[num++].x = 1;
    for(int i=1;i<5;i++){
        if(card[num-1].a == a[i]){
            card[num-1].x++;
        }
        else{
            card[num].a = a[i];
            card[num++].x = 1;
        }
    }
    for(int i=0;i<cnt;i++){
        if(card[i].a == 1){
            card[i].a += 13;
        }
    }
    sort(card,card+cnt,cmp);
    for(int i=0;i<cnt;i++){
        s[x].d[i] = card[i].a;
    }

    if(cnt == 2){//如果有两种牌,只会有两种情况
        it = m.begin();
        if(it->second == 4 || it->second == 1){//其中一种为4张or1张是构成四同
            return 8;
        }
        else{//否则构成三带一对
            return 7;
        }
    }
    else if(cnt == 3){//如果有三种牌,也只会有两种情况
        for(it = m.begin();it != m.end();it++){
            if(it->second == 3){//如果有一种牌有3张构成三同
                return 4;
            }
        }
        return 3;//否则构成两对
    }
    else if(cnt == 4){//如果有四种牌,只会有一种情况,构成对子。
        return 2;
    }
    else if(cnt == 5){//五种牌情况最多,不过可以用是否同花再次区分
        map<int,int>e;
        for(int i=0;i<5;i++){
            e[b[i]]++;
        }
        int num = 0;
        for(it = e.begin();it != e.end();it++){
            num++;
        }
        if(num==1){//同花情况下
            for(int i=2;i<5;i++){//如果有A(1)需要用于区分是皇家同花顺还是普通同花顺所以从2开始循环
                if(a[i] != a[i-1]+1){//如果循环中有不连续的则为同花
                    return 6;
                }
            }//结束后1~4一定为顺子
            if(a[0] == a[4]-12){//如果构成TJQKA
                return 10;
            }
            else if(a[0]+1 == a[1]){//如果构成普通同花顺
                return 9;
            }//后来发现没有必要进行区分,因为后面如果优先度一致时A(1)的点数按最大(14)进行比较
            return 6;//否则为同花
        }
        else{//非同花情况下
            for(int i=2;i<5;i++){
                if(a[i] != a[i-1]+1){//点数不连续构成单张
                    return 1;
                }
            }
            if(a[0]+1==a[1]||a[0] == a[4]-12){//连续构成顺子
                return 5;
            }
            return 1;//点数不连续构成单张
        }
    }
}

int main()
{
    map<char,int>mp;
    mp['C'] = 1;
    mp['D'] = 2;
    mp['H'] = 3;
    mp['S'] = 4;
    for(int i=1;i<=13;i++){
        switch(i)
        {
            case 1:mp['A'] = 1;
            case 10:mp['T'] = 10;
            case 11:mp['J'] = 11;
            case 12:mp['Q'] = 12;
            case 13:mp['K'] = 13;
            default:mp[i+'0'] = i;
        }
    }
    int W;
    int ans;
    char c[5];
    scanf("%d",&W);
    while(W--){
        for(int i=0;i<2;i++){
            for(int j=0;j<5;j++){
                scanf(" %s",s[i].c[j]);
                s[i].a[j] = mp[s[i].c[j][0]];//将点数和花色转化为数字方便后面的排序
                s[i].b[j] = mp[s[i].c[j][1]];//其实后来发现花色没有必要2333
            }
        }
        s[0].level = f(0);
        s[1].level = f(1);
        if(s[0].level == s[1].level){//优先度一样时
            for(int i=0;i<s[0].cnt;i++){//按照张数的多少来优先比较点数
                if(s[0].d[i] == s[1].d[i]){//比到最后一张还是相等的的话
                    if(i==s[0].cnt-1){
                        ans = 2;
                    }
                }
                else{
                    ans = s[0].d[i] > s[1].d[i]? 0:1;//其中某一次第0份or第1份更大即可得出答案
                    break;
                }
            }
        }
        else{
            ans = s[0].level > s[1].level? 0:1;//优先度不一样直接比较
        }
        if(ans == 2){
            printf("Tie");
        }
        else{
            for(int i=0;i<5;i++){
                if(i){
                    printf(" ");
                }
                printf("%s",s[ans].c[i]);

            }
        }
        printf("\n");
    }
}//应该还可以优化,不是很想改了。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值