UVa 10315 - Poker Hands

题目:两个人手里各有五张牌,比较两牌型大小。

比较规则如下:(按优先级排序,优先级相同按下面内部规则比较)

1.straight-flush:同花顺,牌面连续,花色相同,按最大的值比较;

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

3.full-house:船牌,牌面有三个相同值,剩下两个也相同值,按三个的牌面比较;

4.flush:同花,五张牌的花色相同,不是顺子,按牌面最大的开始比,相同比较下一个;

5.straight:顺子,五张牌的值连续,按最大的值比较;

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

7.two-pairs:两对,牌面有两个对子,比较最大的对子,相同比较第二对,相同比较剩下的;

8.one-pair:一对,牌面有一个对子,即两个同值,比对子,相同则按同花比较;

9.highest-card:大牌,没有以上牌型,和同花比较方式相同。

分析:模拟。可以使用条件分支不断判断,不过判断嵌套太多,代码较长。

这里使用一种映射方法,将9种牌型映射到9个互补重叠的单调区间比较;

1.straight-flush:同花顺,区间[13^5+40,13^5+53];

2.four-of-a-kind:四条,区间[13^5+20,13^5+33];

3.full-house:船牌,区间[13^5+1,13^5+14];

4.flush:同花,区间[13^4,13^5];

5.straight:顺子,区间[-20,-5];

6.three-of-a-kind:三条,区间[-40,-25];

7.two-pairs:两对,区间[-8000,-2000];

8.one-pair:一对,区间[-13^5*2,-13^4];

9.highest-card:大牌,区间[-13^5*4,13^5*3];

具体操作参照代码(把数据看成是13进制比较好理解)。

说明:UVa131类似物,╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int value( char ch )
{
	if ( ch == 'T' ) return 8;
	if ( ch == 'J' ) return 9;
	if ( ch == 'Q' ) return 10;
	if ( ch == 'K' ) return 11;
	if ( ch == 'A' ) return 12;
	return ch - '2';
}

int color( char ch )
{
	if ( ch == 'S' ) return 0;
	if ( ch == 'H' ) return 1;
	if ( ch == 'D' ) return 2;
	if ( ch == 'C' ) return 3;
}

int tests(char cards[][3])
{
	//冒泡终于有用武之地了╮(╯▽╰)╭
	for (int i = 5; i > 1; -- i)
		for (int j = 1; j < i; ++ j)
			if (cards[j-1][0] > cards[j][0]) {
				swap(cards[j-1][0], cards[j][0]);
				swap(cards[j-1][1], cards[j][1]);
			}

	int maps[5][13];
    memset(maps, 0, sizeof(maps));
    for (int i = 0; i < 5; ++ i) {
        maps[color(cards[i][1])][value(cards[i][0])] ++;
        maps[4][value(cards[i][0])] ++;
    }
	//royal-flush | straight-flush
	for (int i = 0; i < 4; ++ i)
		for (int j = 0; j < 9; ++ j)
			if (maps[i][j]&maps[i][j+1]&maps[i][j+2]&maps[i][j+3]&maps[i][j+4])
				return 13*13*13*13*13+40+j;
	//four-of-a-kind
	for (int i = 0; i < 13; ++ i)
		if (maps[4][i] >= 4) return 13*13*13*13*13+20+i;
	//full-house
	int three = 0,two = 0;
	for (int i = 12; i >= 0; -- i) {
		if (maps[4][i] == 2)
			two = two*15+i+1;
		if (maps[4][i] == 3)
			three = i+1;
	}
	if (two && three) return 13*13*13*13*13+three+1;
	//flush
	for (int i = 0; i < 4; ++ i) {
		int count = 0, number = 0;
		for (int j = 12; j >= 0; -- j)
			for (int k = 0; k < maps[i][j]; ++ k) {
				++ count;
				number = number*13+j;
			}
		if (count == 5) return number;
	}
	//straight
	for (int i = 0; i < 9; ++ i)
		if (maps[4][i]&maps[4][i+1]&maps[4][i+2]&maps[4][i+3]&maps[4][i+4])
			return i-20;
	//three-of-a-kind
	if (three) return three-40;

	int ans = 0;
	for (int i = 12; i >= 0; -- i)
		if (maps[4][i] == 1)
			ans = ans*13+i;
	//two-pairs
	if (two >= 15) two*15+ans-8000;
	//one-pair
	if (two) return two*13*13*13+ans-13*13*13*13*30;
	//high-card
	return ans-13*13*13*13*50;
}

int main()
{
	char white[5][3],black[5][3];
	while ( ~scanf("%s",black[0]) ) {
		for (int i = 1; i < 5; ++ i)
			scanf("%s",black[i]);
		for (int i = 0; i < 5; ++ i)
			scanf("%s",white[i]);

		int value = tests(black)-tests(white);
		if (value < 0)
			printf("White wins.\n");
		else if (value > 0)
			printf("Black wins.\n");
		else printf("Tie.\n");
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 23:54:54

UVa 10315 - Poker Hands的相关文章

UVa 12585 Poker End Games

题意:Alice和Bob这对狗男女又开始玩游戏了!!!!一开始前者有a元,后者有b元,每次玩,每个人赢得概率是对半开的,令c为a,b中的最小值,那么每次玩,谁输了就给赢的人c元,问Alice赢的概率和游戏的盘数期望值! 思路:貌似会迭代!公式也不好推...发现概率是0.5  然后误差范围是1e-5, 那么只要到达一定深度以后概率就可以忽略不计了! #include <iostream> #include <cstdio> #include <cstring> #incl

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T

计划,,留

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 一.<算法竞赛入门经典> 刘汝佳 (UVaOJ 351道题) 以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html "AOAPC I"

算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发.   一.UVaOJ http://uva.onlinejudge.org  西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ.   二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html   "AO

(Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html “AOAPC I”是刘汝佳(大

ACM-ICPC Dhaka Regional 2012 题解

B: Uva: 12582 - Wedding of Sultan 给定一个字符串(仅由大写字母构成)一个字母表示一个地点,经过这个点或离开这个点都输出这个地点的字母) 问: 每个地点经过的次数(维护一个栈就可以了,注意进入起点和离开起点都不算入起点的次数) #include<cstdio> #include<cstring> #include<stack> #include<iostream> #include<algorithm> using

UVa 131 - The Psychic Poker Player

题目:手里有五张牌,桌上有一堆牌(五张),你可以弃掉手中的k张牌,然后从牌堆中取最上面的k个. 比较规则如下:(按优先级排序) 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

uva 131 The Psychic Poker Player (暴力枚举)

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 sam

UVA 12298 Super Poker II (FFT)

#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N = 1000005; const long double pi = acos(-1.0); struct Complex { long double r,i; Complex(long double r=0, long double i=0):r(r),