UVA - 131 The Psychic Poker Player (暴力枚举+模拟)

 The Psychic Poker Player 

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张牌和桌面最上方的5张牌。
输出你可以拿到的最强的组合。

德州扑克规则:

straight-flush,5张牌花色相同,点数递增1。(8分)
four-of-a-kind,5张牌有4张牌点数相同。(7分)
full-house,5张牌有3张牌点数相同,而且另外2张点数也相同。(6分)
straight,5张牌点数递增1,但是花色不同。(5分)
flush,5张牌花色相同,但是点数没有递增1。(4分)
three-of-a-kind,5张牌有3张点数相同,另外2张点数不同。 4 前3个相同后两个不同,前两个不同,后三个相同。(3分)
two-pairs,5张牌有两对牌点数相同。(2分)
one-pair,5张牌有一对牌点数相同。(1分)
highest-card,木有符合上面任何条件。(0分)

分数越高牌越好
这题没有什么捷径每种情况都要判断,只要有耐心就能AC。

注意:枚举全所有的组合时可以用2进制代替,如果有不懂请看下面的代码。


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f;
int map[255];
//将字符,转化为具体数字
void init() {
	map['A'] = 1; map['2'] = 2;
	map['3'] = 3; map['4'] = 4;
	map['5'] = 5; map['6'] = 6;
	map['7'] = 7; map['8'] = 8;
	map['9'] = 9; map['T'] = 10;
	map['J'] = 11;map['Q'] = 12;
	map['K'] = 13;
}

//保存每种可能
const char result[10][30] = {
	"highest-card",
	"one-pair",
	"two-pairs",
	"three-of-a-kind",	
	"straight",
	"flush",
	"full-house",
	"four-of-a-kind",
	"straight-flush"
};

struct Card{
	char suit; //保存每种花色
	int val; //保存每张牌的值
}card[10];

//顺子
bool flush( int val[]) {	
	if(val[0] == 1 && val[1] == 10 && val[2] == 11 && val[3] == 12 && val[4] == 13) {
		return true;
	}
	for(int i = 0; i < 4; i++) {
		if(val[i+1] - val[i] != 1) {
			return false;
		}
	}
	return true;
}

//同花
bool straight(int suit[]) {
	
	for(int i = 0; i < 4; i++) {
		if(suit[i] != suit[i+1] ) {
			return false;
		}
	}
	return true;
}

//炸弹
bool four(int val[]) {
	if( val[0] == val[1] && val[1] == val[2] && val[2] == val[3]) {
		return true;
	}
	if( val[1] == val[2] && val[2] == val[3] && val[3] == val[4]) {
		return true;
	}
	return false;
}

//三代二
bool house(int val[]) {
	if(val[0] == val[1] && val[1] == val[2] && val[3] == val[4]) {
		return true;
	}
	if(val[0] == val[1] && val[2] == val[3] && val[3] == val[4]) {
		return true;
	}
	return false;
}

//三相同
bool three(int val[]) {
	if(val[0] == val[1] && val[1] == val[2]) {
		return true;
	}
	if(val[1] == val[2] && val[2] == val[3]) {
		return true;
	}
	if(val[2] == val[3] && val[3] == val[4]) {
		return true;
	}
	return false;
}

//两对
bool two(int val[]) {
	if(val[0] == val[1] && val[2] == val[3]) {
		return true;
	}
	if(val[1] == val[2] && val[3] == val[4]) {
		return true;
	}
	if(val[0] == val[1] && val[3] == val[4]) {
		return true;
	}
	return false;
}

//一对
bool one(int val[]) {
	for(int i = 0; i < 4; i++) {
		for(int j = i+1; j < 5; j++) {
			if(val[i] == val[j]) {
				return true;
			}
		}
	}
	return false;
}

int solve(int A[]) {
	int val[5];
	for(int i = 0; i < 5; i++) {
		val[i] = card[A[i]].val;
	}
	sort(val,val+5);
	int suit[5];
	for(int i = 0; i < 5; i++) {
		suit[i] = card[A[i]].suit;
	}
	if( flush(val) && straight(suit)) {
			return 8;
	}else if( four(val)){
		return 7;
	}else if( house(val)) {
		return 6;
	}else if( straight(suit)) { //注意:同花比顺子大
		return 5;
	}else if( flush(val)) {
		return 4; 
	}else if( three(val)) {
		return 3;
	}else if( two(val)) {
		return 2;
	}else if( one(val)) {
		return 1;
	}
	return 0;
}
int main() {
	int sum,maxa;
	char str[10][3];
	init();
	while( scanf("%s",&str[0]) != EOF) {
		card[0].val = map[str[0][0]];
		card[0].suit = str[0][1];
		for(int i = 1; i < 10; i++) {
			scanf("%s",&str[i]);
			card[i].val = map[str[i][0]];
			card[i].suit = str[i][1];
		}
		//input
		int bit[5];
		int A[5];
		int t,p;
		maxa = -INF;
		for(bit[0] = 0; bit[0] <= 1; bit[0]++) {
			for(bit[1] = 0; bit[1] <= 1; bit[1]++) {
				for(bit[2] = 0; bit[2] <= 1; bit[2]++) {
					for(bit[3] = 0; bit[3] <= 1; bit[3]++) {
						for(bit[4] = 0; bit[4] <= 1; bit[4]++) {
							p = 0; 
							for(int i = 0; i < 5; i++) {
								if(bit[i])
									A[p++] = i;
							}
							t = p;
							for(int i = 5; i < 10-t; i++) {
								A[p++] = i;
							}
							sum = solve(A);
							maxa = max(maxa,sum);
						}
					}
				}
			}
		}
		//Print
		printf("Hand: ");
		for(int i = 0; i < 5; i++) {
			printf("%s ",str[i]);
		}
		printf("Deck: ");
		for(int i = 5; i < 10; i++) {
			printf("%s ",str[i]);
		}
		printf("Best hand: ");
		printf("%s\n",result[maxa]);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值