Texas hold'em Poker 2019 沈阳网络赛

Texas hold’em Poker

Time limit1000 ms
Memory limit262144K

Recently, Yang was addicted to Texas hold’em Poker. So he found a lot of people to play with him. Due to the large number of people, Yang had to change the rules of the game:
All poker cards are counted by number without suit.
Each card has a value which is one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 (denoted A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K)
Each player drew five poker cards from a complete deck of poker (without jokers), and the possible hand values are ranked as follows from lowest to highest:
High Card. Hands which do not fit any higher category are ranked by the sum of all the cards.
Pair. 2 of the 5 cards in the hand have the same value. Hands which both contain a pair are ranked by the value of the cards forming the pair. If these values are the same, the hands are ranked by the sum of the rest cards.
Two Pairs. The hand contains 2 different pairs. Hands which both contain 2 pairs are ranked by the value of their highest pair. Hands with the same highest pair are ranked by the value of their other pair. If these values are the same the hands are ranked by the value of the remaining card.
Three of a Kind. Three of the cards in the hand have the same value. Hands which both contain three of a kind are ranked by the value of the 3 cards. Hands with the same 3 cards are ranked by the sum of the rest two cards.
Full House. 3 cards of the same value, with the remaining 2 cards forming a pair. Ranked by the value of the 3 cards. Hands with the same 3 cards are ranked by the value of the cards forming the pair.
Four of a kind. 4 cards with the same value. Ranked by the value of the 4 cards. Hands with the same 4 cards are ranked by the remaining card.
Straight. Hand contains 5 cards with consecutive values. Hands which both contain a straight are ranked by their highest card.
Royal Straight. Straight from 10 to A (10-J-Q-K-A). The largest hand!
Now, Yang has known everyone’s cards, he wants a ranking list of all poker hands. If the value of players are equal, output their names in lexicographical order. It’s guaranteed that no one’s name repeats. Can you just help him?

  • Input
    The input consists of multiple test cases, Each test case starts with a number n ( 1 ≤ n ≤ 1 0 5 , 1 ≤ n ≤ 1 0 5 ) (1 \le n \le 10^5,1≤n≤10 ^ 5 ) (1n105,1n105) represents the number of players, Then followed nn lines with each line two string m ( 1 ≤ ∣ m ∣ ≤ 10 , 1 ≤ ∣ m ∣ ≤ 10 ) (1 \le |m| \le 10,1≤∣m∣≤10) (1m10,1m10) – the name of the player s ( 1 ≤ ∣ s ∣ ≤ 10 , 1 ≤ ∣ s ∣ ≤ 10 ) (1 \le |s| \le 10,1≤∣s∣≤10) (1s10,1s10) the poker cards of the player.

  • Output
    For each test case, you should output nn lines represent the ranking list.

  • Sample Input
    3
    Alice AAA109
    Bob 678910
    Boa 678910

  • Sample Output
    Boa
    Bob
    Alice

题意就是根据卡牌的不同搭配赋以不同的值,输出值的排名。如果玩家的值相等,则按字典顺序输出其名称,保证没有人重复名字
可能的手牌值从高到低排列如下
皇家顺子:直接从10到A
顺子:一手牌包含5张连续值的卡,两个都包含顺子的牌按其最高牌排名
四张:4张相同价值的卡,按4张卡的价值排名,拥有相同4张牌的手按剩余卡牌排名
满牌:3张相同价值的卡,其余2张卡组成一对,按3张卡的价值排名,拥有相同3张牌的手按构成该对的牌的值排名
三张:手中的三张卡具有相同的值,双手都包含三种的手牌按3张牌的价值排名,拥有相同3张牌的手按其余两张牌的总和排名
两对:手里有2对不同的对,都有2对的手牌按其最高对的值排序,最高对的手牌相同按另一对的值排名。如果这些值相同,则按剩余卡的值进行排名
:手中的5张卡中有2张具有相同的值。都包含一对的手按构成该对的牌的值进行排名。如果这些值相同,则手牌按其余牌的总和排名
卡牌:不适合任何较高级别的牌将按所有牌的总和排名

写了个好复杂的模拟emmm,因为卡牌值最多比三次,比如两对的时候先按两对的大值比较,再比另一对最后比剩余卡。所以最重要的是大档次,用第几档乘以1000000表示,后面依次下去

#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;

struct node{
  char name[15];
  int value;
}number[100005];

bool compare(node a, node b) {
  if(a.value == b.value) return strcmp(a.name, b.name) < 0;
  //值相等按名字字典序排名
  return a.value > b.value;
}

int main(int argc, char const *argv[]) {
  int n;
  char c;
  int card[13];
  while(~scanf("%d", &n)) {
    for (int i = 0; i < n; i++) {
      scanf("%s", number[i].name);
      memset(card, 0, sizeof(card));
      for (int j = 0; j < 5; j++) {
        scanf(" %c", &c);
        switch (c) {
          case 'A': card[0]++; break;
          case '1': card[9]++; scanf("%c", &c); break;
          //因为卡牌没有1所以一定是卡牌10
          case 'J': card[10]++; break;
          case 'Q': card[11]++; break;
          case 'K': card[12]++; break;
          default : card[c-'1']++;
        }
        //存手牌
      }
      for (int j = 0; j < 13; j++) {
        if(card[j] >= 2) {
          if (card[j] == 4) {
            number[i].value += 6*1000000 + j*10000;//四张的卡牌值
          }
          else {
            if (card[j] == 3) {
              if(number[i].value / 1000000) number[i].value = 5*1000000 + j*10000 + ((number[i].value/10000-(number[i].value/1000000)*100))*100;//如果前面有对子,也就是说是满牌,第五档值加上之前第二档的降值
              else number[i].value += 4*1000000 + j*10000;//不是满牌,按三张算
            }
            else {//有对子
              if(number[i].value / 1000000) {//之前有对子或三张
                if(number[i].value / 1000000 == 4) number[i].value += 1000000 + j*100;//之前是三张,从第四档变成第五档,加上对子的值
                else {//之前是对子
                  int temp = number[i].value/10000-(number[i].value/1000000)*100;
                  number[i].value += 1000000 + (j-temp)*10000 + temp*100;
                }
              }
              else number[i].value += 2*1000000 + j*10000;//只有对子
            }
          }
        }
        else if(card[j]) number[i].value += j;//加上单张的价值
      }
      if (number[i].value / 100 == 0) {//没有两张以上相同的牌,判断是否顺子
        if (card[0]+card[9]+card[10]+card[11]+card[12] == 5) {
          number[i].value = 8*1000000;//皇家顺子
          continue;
        }
        for (int h = 0; h < 9; h++) {
          if (card[h]+card[h+1]+card[h+2]+card[h+3]+card[h+4]==5) {
            number[i].value = 7*1000000 + (h+4)*10000;//顺子
            break;
          }
        }
      }
    }
    sort(number, number+n, compare);//按值和字典序排序
    for (int i = 0; i < n; i++) {
      printf("%s\n", number[i].name);
    }
  }
  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值