PE54 Poker Hands
题意
德州扑克是这样的一个游戏:
玩家 1(Player1)和 玩家 2(Player2)各有 \(5\) 张牌(card),这 \(5\) 张 card 称为 PlayingCard,每张 card 用一个长度为 \(2\) 的字符串表示。
card 的输入格式如下:
- 第一个字符为 card 的 点数(number),大小关系为:\(2<3<4<5<6<7<8<9<\text{T}<\text{J}<\text{Q}<\text{K}<\text{A}\)。
- 第二个字符为 card 的 花色(suit),大小关系你没必要知道。
每个 PlayingCard 都是以下 \(10\) 种类型(kind)中的一种,大小关系为从小到大:
- 高牌(High Card):什么都不是。
- 一个对子(One Pair):存在 \(2\) 张 number 相同的 card(这被称为 pair)。
- 两个对子(Two Pairs):存在两个不同的 pair。
- 三条(Three of a Kind):存在 \(3\) 张 number 相同的 card(这被称为 tuple)。
- 顺子(Straight):\(5\) 张 card 为连续的 card。
- 同花(Flush):\(5\) 张 card 的 suit 相同。
- 三带二(Full House):点数不同的 tuple 和 pair。
- 炸弹(Four of a Kind):存在 \(4\) 张 number 相同的 card(这被称为 bomb)。
- 同花顺(Straight Flush):既是 Straight 又是 Flush。
- 皇家同花顺(Royal Flush):Straight 为 \(\text{TJQKA}\) 的 Straight Flush。
当 Player1 和 Player2 的 PlayingCard 的 kind 相同时,按照以下规则比较:
- 若双方都为 Straight 或 Straight Flush,则比较 Straight 中最小的那副牌(StraightStart),StraightStart number 更大的胜出;
- 若双方都为 bomb,bomb number 更大的胜出;
- 若双方都有 tuple,tuple number 更大的胜出;
- 若双方都有 pair1,pair1 number 更大的胜出;
- 若双方都有 pair2,pair2 number 更大的胜出;
- 若经上述步骤仍无法比较,则先比较双方最大的 card 的 number,更大的胜出;否则继续比较次大的;以此类推。
现给出了 \(1000\) 局游戏 Player1 和 Player2 的 PlayingCard(前 \(5\) 张为 Player1 的,后 \(5\) 张为 Player2 的),求有多少局游戏是 Player1 胜出。
输入在 poker.txt 中。
思路
题意已经把思路讲的够清晰了,直接模拟即可。
#include<bits/stdc++.h>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int T=1000;
map<char,int> CardToNumber;
void SetMap(){
CardToNumber['2']=2;
CardToNumber['3']=3;
CardToNumber['4']=4;
CardToNumber['5']=5;
CardToNumber['6']=6;
CardToNumber['7']=7;
CardToNumber['8']=8;
CardToNumber['9']=9;
CardToNumber['T']=10;
CardToNumber['J']=11;
CardToNumber['Q']=12;
CardToNumber['K']=13;
CardToNumber['A']=14;
}
struct PlayingCard{
string cards[6];
int number[6];char suit[6];
int cnt[15];
int kind;
//kind=0: High Card
//kind=1: One Pair
//kind=2: Two Pairs
//kind=3: Three of a Kind
//kind=4: Straight
//kind=5: Flush
//kind=6: Full House
//kind=7: Four of a Kind
//kind=8: Straight Flush
//kind=9: Royal Flush
int StraightStart;
bool IsFlush;
int bomb;
int pair1,pair2;
int tuple;
void input(){
memset(cnt,0,sizeof(cnt));
kind=0;
StraightStart=0;
IsFlush=false;
bomb=0;
pair1=pair2=0;
tuple=0;
forUp(i,1,5)cin>>cards[i];
forUp(i,1,5){
number[i]=CardToNumber[cards[i][0]];
suit[i]=cards[i][1];
++cnt[number[i]];
}
sort(number+1,number+6,greater<int>());
}
bool isStraight(){
forUp(i,2,10){
bool flag=true;
forUp(j,i,i+4)if(cnt[j]==0)flag=false;
if(flag){
StraightStart=i;
kind=4;
return true;
}
}
return false;
}
bool isFlush(){
IsFlush=true;
forUp(i,2,5)if(suit[i]!=suit[1])IsFlush=false;
if(IsFlush)kind=5;
return IsFlush;
}
bool isBomb(){
forUp(i,2,14){
if(cnt[i]==4){
bomb=i;
kind=7;
return true;
}
}
return false;
}
void FindPair(){
int PairCnt=0;
forDown(i,14,2){
if(cnt[i]==2){
++PairCnt;
if(PairCnt==1)pair1=i;
if(PairCnt==2)pair2=i;
}
}
}
void FindTuple(){
forUp(i,2,14){
if(cnt[i]==3){
tuple=i;
break;
}
}
}
void CheckPlayingCard(){
if(isStraight()&&isFlush()){
if(StraightStart==10)kind=9;
else kind=8;
}
if(StraightStart!=0||IsFlush)return;
if(isBomb())return;
FindPair();
FindTuple();
if(tuple!=0){
if(pair1!=0)kind=6;
else kind=3;
}
else{
if(pair2!=0)kind=2;
else if(pair1!=0)kind=1;
}
}
};
PlayingCard Player1,Player2;
int CheckWhoIsWinner(){
Player1.CheckPlayingCard();
Player2.CheckPlayingCard();
if(Player1.kind>Player2.kind)return 1;
if(Player1.kind<Player2.kind)return 2;
int kind=Player1.kind;
if(kind==4||kind==8){
if(Player1.StraightStart>Player2.StraightStart)return 1;
if(Player1.StraightStart<Player2.StraightStart)return 2;
}
if(kind==7){
if(Player1.bomb>Player2.bomb)return 1;
if(Player1.bomb<Player2.bomb)return 2;
}
if(kind==3||kind==6){
if(Player1.tuple>Player2.tuple)return 1;
if(Player1.tuple<Player2.tuple)return 2;
}
if(kind==1||kind==2||kind==6){
if(Player1.pair1>Player2.pair1)return 1;
if(Player1.pair1<Player2.pair1)return 2;
}
if(kind==2){
if(Player1.pair2>Player2.pair2)return 1;
if(Player1.pair2<Player2.pair2)return 2;
}
forUp(i,1,5){
if(Player1.number[i]>Player2.number[i])return 1;
if(Player1.number[i]<Player2.number[i])return 2;
}
return -1;
}
int solve(){
Player1.input();
Player2.input();
return CheckWhoIsWinner();
}
int ans;
int main(){
SetMap();
forUp(i,1,T)ans+=solve()==1;
cout<<ans;
return 0;
}

浙公网安备 33010602011771号