uva131 The Psychic Poker Player

Time Limit: 3000MS     64bit IO Format: %lld & %llu
Description

In 5-card draw poker, a player is dealt a hand of five cards (which may be looked at). The player may then discard between zero and five of his or her cards and have them replaced by the same number of cards from the top of the deck (which is face down). The object is to maximize the value of the final hand. The different values of hands in poker are given at the end of this problem.

Normally the player cannot see the cards in the deck and so must use probability to decide which cards to discard. In this problem, we imagine that the poker player is psychic and knows which cards are on top of the deck. Write a program which advises the player which cards to discard so as to maximize the value of the resulting hand.

Input and Output

Input will consist of a series of lines, each containing the initial five cards in the hand then the first five cards on top of the deck. Each card is represented as a two-character code. The first character is the face-value (A=Ace, 2-9, T=10, J=Jack, Q=Queen, K=King) and the second character is the suit (C=Clubs, D=Diamonds, H=Hearts, S=Spades). Cards will be separated by single spaces. Each input line will be from a single valid deck, that is there will be no duplicate cards in each hand and deck.

Each line of input should produce one line of output, consisting of the initial hand, the top five cards on the deck, and the best value of hand that is possible. Input is terminated by end of file.

Use the sample input and output as a guide. Note that the order of the cards in the player's hand is irrelevant, but the order of the cards in the deck is important because the discarded cards must be replaced from the top of the deck. Also note that examples of all types of hands appear in the sample output, with the hands shown in decreasing order of value.

Sample Input

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

Sample Output

Hand: TH JH QC QD QS Deck: QH KH AH 2S 6S Best hand: straight-flush
Hand: 2H 2S 3H 3S 3C Deck: 2D 3D 6C 9C TH Best hand: four-of-a-kind
Hand: 2H 2S 3H 3S 3C Deck: 2D 9C 3D 6C TH Best hand: full-house
Hand: 2H AD 5H AC 7H Deck: AH 6H 9H 4H 3C Best hand: flush
Hand: AC 2D 9C 3S KD Deck: 5S 4D KS AS 4C Best hand: straight
Hand: KS AH 2H 3C 4H Deck: KC 2C TC 2D AS Best hand: three-of-a-kind
Hand: AH 2C 9S AD 3C Deck: QH KS JS JD KD Best hand: two-pairs
Hand: 6C 9C 8C 2D 7C Deck: 2H TC 4C 9S AH Best hand: one-pair
Hand: 3D 5S 2H QD TD Deck: 6S KH 9H AD QH Best hand: highest-card

題目大意如下:這是一幾局德州撲克遊戲。給定5張初始手牌和5張牌的牌堆(可預知牌堆中的牌類、數字、花色以及順序,即玩傢俱有超能力),可以拿手牌換牌堆最上方的牌,之後手牌丟棄,換到的牌不允許再換。

思路如下:先確定枚舉和搜索的對象,本題的對象應該是要棄的手牌,由於考慮到換牌的數量和制定牌不定,我們要用到子集枚舉的算法。而這裏我們用增量法。

用string類配合cin(string是類,不能用scanf或printf,所以果斷用cin和cout)之後,預處理牌的點數,將2~9和A、T、J、Q、K統一轉化爲數字。之後,用增量法枚舉要換的牌,之後使用judge函數對它的花色和點數進行判斷,這裏要外加一個sort優化方便直接用if語句判斷,記錄最高分手牌則用一個常數數組記錄同花順~大牌的降序字符串數組,用數組的下標值來比較,記錄最小值ans,最後按題目要求輸出。

代碼如下:(2KB)

#include<string>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
string cd[11];
string bthd[]={"straight-flush","four-of-a-kind","full-house","flush","straight","three-of-a-kind","two-pairs","one-pair","highest-card"};
int val[11],a[11],hd[6],ans;
int jud(int cur)
{
	bool samecol=1;
	for(int i=0;i<cur;i++){
		hd[i]=val[a[i]];
		if(cd[a[0]][1]!=cd[a[i]][1])samecol=0;
	}
	for(int i=cur;i<5;i++){
		hd[i]=val[5+i-cur];
		if(cd[a[0]][1]!=cd[5+i-cur][1])samecol=0;
	}
	sort(hd,hd+5);
	bool flush=1;
	for(int i=0;i<4;i++)
		if((i||hd[0]!=1||hd[4]!=13)&&hd[i]+1!=hd[i+1])
			{flush=0;break;}
	if(samecol&&flush)return 0;
	if((hd[0]==hd[1]||hd[3]==hd[4])&&hd[1]==hd[2]&&hd[2]==hd[3])return 1;
	if((hd[0]==hd[1]&&hd[1]==hd[2]&&hd[3]==hd[4])||(hd[0]==hd[1]&&hd[2]==hd[3]&&hd[3]==hd[4]))return 2;
	if(samecol)return 3;
	if(flush)return 4;
	if((hd[0]==hd[1]&&hd[1]==hd[2])||(hd[1]==hd[2]&&hd[2]==hd[3])||(hd[2]==hd[3]&&hd[3]==hd[4]))return 5;
	if(((hd[0]==hd[1])&&(hd[2]==hd[3]||hd[3]==hd[4]))||(hd[1]==hd[2]&&hd[3]==hd[4]))return 6;
	if(hd[0]==hd[1]||hd[1]==hd[2]||hd[2]==hd[3]||hd[3]==hd[4])return 7;
	return 8;
}
void sub(int cur)
{
	ans=min(ans,jud(cur));
	int s=cur?a[cur-1]+1:0;
	for(int i=s;i<5;i++){
		a[cur]=i;
		sub(cur+1);
	}
}
void solve()
{
	for(int i=0;i<10;i++){
		if(cd[i][0]=='T')val[i]=10;
		else if(cd[i][0]=='J')val[i]=11;
		else if(cd[i][0]=='Q')val[i]=12;
		else if(cd[i][0]=='K')val[i]=13;
		else if(cd[i][0]=='A')val[i]=1;
		else val[i]=cd[i][0]-'0';
	}
	ans=8;
	sub(0);
}
void out()
{
	cout<<"Hand: ";
	for(int i=0;i<5;i++)
		cout<<cd[i]<<" ";
	cout<<"Deck: ";
	for(int i=5;i<10;i++)
		cout<<cd[i]<<" ";
	cout<<"Best hand: "<<bthd[ans]<<endl;
}
int main()
{
	while(cin>>cd[0]){
		for(int i=1;i<10;i++)
			cin>>cd[i];
		solve();
		out();
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章