week9 模拟打牌

题目:

最近,东东沉迷于打牌。所以他找到 HRZ、ZJM 等人和他一起打牌。由于人数众多,东东稍微修改了亿下游戏规则:

所有扑克牌只按数字来算大小,忽略花色。
每张扑克牌的大小由一个值表示。A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K 分别指代 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13。
每个玩家抽得 5 张扑克牌,组成一手牌!(每种扑克牌的张数是无限的,你不用担心,东东家里有无数副扑克牌)

理所当然地,一手牌是有不同类型,并且有大小之分的。

举个栗子,现在东东的 “一手牌”(记为 α),瑞神的 “一手牌”(记为 β),要么 α > β,要么 α < β,要么 α = β。

那么这两个 “一手牌”,如何进行比较大小呢?首先对于不同类型的一手牌,其值的大小即下面的标号;对于同类型的一手牌,根据组成这手牌的 5 张牌不同,其值不同。下面依次列举了这手牌的形成规则:

1大牌:这手牌不符合下面任一个形成规则。如果 α 和 β 都是大牌,那么定义它们的大小为组成这手牌的 5 张牌的大小总和。

2 对子:5 张牌中有 2 张牌的值相等。如果 α 和 β 都是对子,比较这个 “对子” 的大小,如果 α 和 β 的 “对子” 大小相等,那么比较剩下 3 张牌的总和。

3 两对:5 张牌中有两个不同的对子。如果 α 和 β 都是两对,先比较双方较大的那个对子,如果相等,再比较双方较小的那个对子,如果还相等,只能比较 5 张牌中的最后那张牌组不成对子的牌。

4 三个:5 张牌中有 3 张牌的值相等。如果 α 和 β 都是 “三个”,比较这个 “三个” 的大小,如果 α 和 β 的 “三个” 大小相等,那么比较剩下 2 张牌的总和。

5 三带二:5 张牌中有 3 张牌的值相等,另外 2 张牌值也相等。如果 α 和 β 都是 “三带二”,先比较它们的 “三个” 的大小,如果相等,再比较 “对子” 的大小。

6 炸弹:5 张牌中有 4 张牌的值相等。如果 α 和 β 都是 “炸弹”,比较 “炸弹” 的大小,如果相等,比较剩下那张牌的大小。

7顺子:5 张牌中形成 x, x+1, x+2, x+3, x+4。如果 α 和 β 都是 “顺子”,直接比较两个顺子的最大值。

8 龙顺:5 张牌分别为 10、J、Q、K、A。

作为一个称职的魔法师,东东得知了全场人手里 5 张牌的情况。他现在要输出一个排行榜。排行榜按照选手们的 “一手牌” 大小进行排序,如果两个选手的牌相等,那么人名字典序小的排在前面。

不料,此时一束宇宙射线扫过,为了躲避宇宙射线,东东慌乱中清空了他脑中的 Cache。请你告诉东东,全场人的排名

输入:

输入包含多组数据。每组输入开头一个整数 n (1 <= n <= 1e5),表明全场共多少人。
随后是 n 行,每行一个字符串 s1 和 s2 (1 <= |s1|,|s2| <= 10), s1 是对应人的名字,s2 是他手里的牌情况。

输出:

对于每组测试数据,输出 n 行,即这次全场人的排名。

样例输入:

3
DongDong AAA109
ZJM 678910
Hrz 678910

样例输出:

Hrz
ZJM
DongDong

题解:

这一题,我们就是暴力对五张牌进行比较。统计大小相同的牌的个数以及花色相同的牌的个数,分别放入统计数组中,之后在统计相同个数有多少个(就是两张一样的有多少对,三张一样的有多少)。之后对需要满足的条件进行比较,不过满足就将choice数组相应的位置变一,之后输出最小置一的位置就是其牌型。
这个题其实就是考察我们码力的一个问题,看看你是否能够找到这些牌型所对应的判断条件。
之后我们按照他们的优先级判断牌的大小,输出我们的选手即可。

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string.h>
#include <string>
using namespace std;
char card[13] = { 'A','2','3','4','5','6','7','8','9','1','J','Q','K' };
struct mem {
	string name;
	int x, y, z, w;
	mem() {}
	mem(string thename, int a, int b, int c, int d) {
		name = thename; x = a; y = b; z = c; w = d;
	}
};


mem p[100010];
bool cmp(const mem& a, const mem& b) {
	if (a.x == b.x) {
		if (a.y == b.y) {
			if (a.z == b.z) {
				if (a.w == b.w) {
					return a.name < b.name ? 1 : 0;
				}
				else { return a.w > b.w; }
			}
			else { return a.z > b.z; }
		}
		else { return a.y > b.y; }
	}
	else { return a.x > b.x; }
}


bool shunzi(int pai[], int* a) { 
	if (pai[0] == pai[1] - 1 && pai[1] == pai[2] - 1 && pai[2] == pai[3] - 1 && pai[3] == pai[4] - 1) {
		a[0] = 7; a[1] = pai[4]; a[2] = 0; a[3] = 0;
		return 1;
	}
	return 0;
}

bool longshun(int pai[], int* a) {
	if (pai[0] == 0 && pai[1] == 9 && pai[2] == 10 && pai[3] == 11 && pai[4] == 12) {
		a[0] = 8; a[1] = 0; a[2] = 0; a[3] = 0;
		return 1;
	}
	return 0;
}

bool zhadan(int pai[], int* a) {
	if (pai[0] == pai[1] && pai[1] == pai[2] && pai[2] == pai[3]) {
		a[0] = 6; a[1] = pai[0]; a[2] = pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[4] == pai[1] && pai[1] == pai[2] && pai[1] == pai[3]) {
		a[0] = 6; a[1] = pai[4]; a[2] = pai[0]; a[3] = 0;
		return 1;
	}
	return 0;
}

bool sandaier(int pai[], int* a) { 
	if (pai[0] == pai[1] && pai[1] == pai[2] && pai[3] == pai[4]) {
		a[0] = 5; a[1] = pai[0]; a[2] = pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[0] == pai[1] && pai[2] == pai[3] && pai[2] == pai[4]) {
		a[0] = 5; a[1] = pai[4]; a[2] = pai[0]; a[3] = 0;
		return 1;
	}
	return 0;
}

bool sange(int pai[], int* a) {
	if (pai[0] == pai[1] && pai[1] == pai[2]) {
		a[0] = 4; a[1] = pai[0]; a[2] = pai[3] + pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[3] == pai[1] && pai[1] == pai[2]) {
		a[0] = 4; a[1] = pai[1]; a[2] = pai[0] + pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[3] == pai[4] && pai[3] == pai[2]) {
		a[0] = 4; a[1] = pai[2]; a[2] = pai[1] + pai[0]; a[3] = 0;
		return 1;
	}
	return 0;
}

bool liangdui(int pai[], int* a) {
	if (pai[0] == pai[1] && pai[2] == pai[3]) {
		if (pai[0] > pai[2]) {
			a[0] = 3; a[1] = pai[0]; a[2] = pai[2]; a[3] = pai[4];
		}
		else {
			a[0] = 3; a[1] = pai[2]; a[2] = pai[0]; a[3] = pai[4];
		}
		return 1;
	}
	if (pai[1] == pai[2] && pai[3] == pai[4]) {
		if (pai[3] > pai[2]) {
			a[0] = 3; a[1] = pai[3]; a[2] = pai[2]; a[3] = pai[0];
		}
		else {
			a[0] = 3; a[1] = pai[2]; a[2] = pai[3]; a[3] = pai[0];
		}
		return 1;
	}
	if (pai[0] == pai[1] && pai[3] == pai[4]) {
		if (pai[1] > pai[3]) {
			a[0] = 3; a[1] = pai[1]; a[2] = pai[3]; a[3] = pai[2];
		}
		else {
			a[0] = 3; a[1] = pai[3]; a[2] = pai[1]; a[3] = pai[2];
		}
		return 1;
	}
	return 0;
}

bool duizi(int pai[], int* a) {
	if (pai[0] == pai[1]) {
		a[0] = 2; a[1] = pai[1]; a[2] = pai[2] + pai[3] + pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[1] == pai[2]) {
		a[0] = 2; a[1] = pai[1]; a[2] = pai[0] + pai[3] + pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[2] == pai[3]) {
		a[0] = 2; a[1] = pai[2]; a[2] = pai[1] + pai[0] + pai[4]; a[3] = 0;
		return 1;
	}
	if (pai[3] == pai[4]) {
		a[0] = 2; a[1] = pai[3]; a[2] = pai[2] + pai[1] + pai[0]; a[3] = 0;
		return 1;
	}
	return 0;
}

bool dapai(int pai[], int* a) {
	a[0] = 1; a[1] = pai[0] + pai[1] + pai[3] + pai[2] + pai[4];
	a[2] = 0; a[3] = 0;
	return 1;
}

int* cont(int pai[]) {
	sort(pai, pai + 5);
	int* a = new int[4];
	if (shunzi(pai, a)) { return a; }
	if (longshun(pai, a)) { return a; }
	if (zhadan(pai, a)) { return a; }
	if (sandaier(pai, a)) { return a; }
	if (sange(pai, a)) { return a; }
	if (liangdui(pai, a)) { return a; }
	if (duizi(pai, a)) { return a; }
	dapai(pai, a);

	return a;
}
int main(int argc, char** argv) {
	int n; scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		string nam;
		char b;
		int pai[5]; 
		cin >> nam;
		
		for (int j = 0; j < 5; j++) {
		
			cin >> b;
			
			for (int k = 0; k < 13; k++) {
				if (b == card[k]) {
					if (b == '1') { scanf("%c", &b); }
					pai[j] = k; break;
				}
				
			}
		} 
		int* a = cont(pai);
		p[i].name = nam;
		p[i].x = a[0]; p[i].y = a[1];
		p[i].z = a[2]; p[i].w = a[3];
	}
	sort(p, p + n,cmp);
	for (int i = 0; i < n; i++) {
		cout << p[i].name << endl;
		
	}
	return 0;
}

反思:

对于代码量比较大的题目,我们需要耐下心来慢慢的来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值