PE54 Poker Hands

ProjectEuler 链接

题意

德州扑克是这样的一个游戏:

玩家 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;
}
posted @ 2025-04-08 21:02  LXcjh4998  阅读(85)  评论(0)    收藏  举报