UVA 131 - The Psychic Poker Player

题目大意:你手中有五张牌,桌上叠着五张牌,你有超能力,可以让任意张手中的牌与桌上的任意张交换,使得交换以后手中与桌上依旧五张牌。问你交换的最好结果为何种牌?

解题思路:德州扑克的规则,又有一些细节不同。规则如下:

1.straight-flush:同花顺,牌面为T(10) - A,这里不论花色是否相同;

2.four-of-a-kind:四条,牌面有4个相同的值;

3.full-house:船牌,牌面有3个相同值,剩下2个也相同值;

4.flush:同花,五张牌的花色相同,不是同花顺;

5.straight:顺子,五张牌的值连续,A可以作为1也可以作为14;

6.three-of-a-kind:三条,牌面有3个相同的值;

7.two-pairs:两对,牌面有2个对子;

8.one-pair:一对,牌面有一个对子,即2个同值;

9.highest-card:大牌,没有以上牌型。

了解规则以后,用子集生成法的增量构造法,枚举所有手中保留的为原手牌的哪一些,取出桌面上的那些牌也确定了。然后就是判断比较麻烦一些。严格遵守规则就好。顺子的判断,我是用了一个数组存手上的牌的值,要注意不越界。

ac代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char hand[5][5], desk[5][5], kind[10][50];
int re, a[5];
struct node{
	int value;
	int color;
}own[5];
void init()
{
	re = 8;
	strcpy(kind[0], "straight-flush");
	strcpy(kind[1], "four-of-a-kind");   
	strcpy(kind[2], "full-house");   
	strcpy(kind[3], "flush");   
	strcpy(kind[4], "straight");   
	strcpy(kind[5], "three-of-a-kind");   
	strcpy(kind[6], "two-pairs");   
	strcpy(kind[7], "one-pair");   
	strcpy(kind[8], "highest-card");       
}
int tran(char ch)
{
	if (ch == 'K')
		return 13;
	if (ch == 'Q')
		return 12;
	if (ch == 'J')
		return 11;
	if (ch == 'T')
		return 10;
	if (ch == 'A')
		return 1;
return ch-'0';
}
void hand_card(int n)
{
	for (int i=0; i<n; i++){
		own[i].value = tran(hand[ a[i] ][0]);	
		own[i].color = hand[ a[i] ][1];
	}
	for (int i=n,j=0; i<5; i++,j++){
		own[i].value = tran(desk[j][0]);
		own[i].color = desk[j][1];
	}
}
bool compare(node a, node b)
{
	if (a.value != b.value)
		return a.value < b.value;
	return a.color < b.color;
}
void best()
{
	int three_kind, two_kind, num[14], temp;
	memset(num, 0, sizeof(num));
	three_kind = two_kind = 0;
	sort(own, own+5, compare);
	for (int i=0; i<5; i++)
		num[own[i].value]++;
	if (num[1] && num[10] && num[11] && 
	num[12] && num[13])
		re = 0;
	for (int i=0; i<=13; i++){
		if (num[i] == 4 && re > 1)
			re = 1;
		else if (num[i] == 2)
			two_kind++;
		else if (num[i] == 3)
			three_kind++;
	}
	if (three_kind && two_kind && re > 2)
		re = 2;			
	if (own[0].color == own[1].color && 
	own[1].color == own[2].color &&
	own[2].color == own[3].color && 
	own[3].color == own[4].color && re > 3)
			re = 3;
	temp = own[0].value;
	if (num[temp%14] && num[(temp+1)%14] && num[(temp+2)%14] 
	&& num[(temp+3)%14] && num[(temp+4)%14] && re > 4)
		re = 4;		
	if (three_kind && re > 5)
		re = 5;
	if (two_kind == 2 && re > 6)
		re = 6;
	if (two_kind && re > 7)
		re = 7;
}

void solve(int cur)
{
	int minu=0;
	hand_card(cur);
	best();
	if (cur)
		minu = a[cur-1] + 1;
	for (int i=minu; i<5; i++){
		a[cur] = i;
		solve(cur+1);
	}
}

int main()
{
	while (scanf("%s", &hand[0])!=EOF){
		init();
		for (int i=1; i<5; i++)
			scanf("%s", &hand[i]);
		for (int i=0; i<5; i++)
			scanf("%s", &desk[i]);
		printf("Hand: ");
		for (int i=0; i<5; i++)
			printf("%s ", hand[i]);
		solve(0);
		printf("Deck: ");
		for (int i=0; i<5; i++)
			printf("%s ", desk[i]);
		printf("Best hand: %s\n", kind[re]);
	}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值