最近,阿夸迷于德州扑克。所以她找到了很多人和她一起玩。由于人数众多,阿夸必须更改游戏规则:
现在,阿夸已经知道了每个人的手牌,她想要知道所有人的排名列表。如果玩家的手牌大小相等,则按玩家名字的字典序输出。保证没有重复的名字。你能帮帮她吗?
输入格式:
第一行包含一个正整数 N (1<=N<=100000) ,表示玩家的人数。
接下来 N 行,每行包含两个字符串:m (1<=|m|<=10 ) ,表示玩家的名字;s (1<=|s|<=10),表示玩家的手牌。
输出格式:
输出 N个玩家的排名列表。
输入:
3
Alice AAA109
Bob 678910
Boa 678910
输出:
Boa
Bob
Alice
转换牌面:将字符数组转换为数字数组
对每一副牌的牌面排序,分类判断各种牌型,并计算对应的分值: (关键步骤)
按牌型、分值、姓名排序:采用结构体数组快速排序的方法
#include<stdio.h>
#include<string.h>
#include <algorithm>
using namespace std;
char num[15] = "0A234567891JQK";
struct member {
char name[15];
char card1[15];
int card2[15];
int level,score,two1,two2,three,four;
}man[120000];
void convert(char str[], int x[]) {
int i, j, k;
for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
for (k = 1;; k++) {
if (num[k] == str[i]) {
x[j] = k;
break;
}
}
if (x[j] == 10) {
i++;
}
}
}/*功能:转换牌面
参数:str 为字符牌面,x 为数字牌面*/
void judge(member a,int x) {
int i;
for (i = 0; i < 5; i++) {
a.score+= a.card2[i];
}
for (i = 0; i<4; i++) {
if (a.card2[i] == a.card2[i + 1]) {
a.two1= a.card2[i];
}
if (a.card2[i] == a.card2[i + 2]) {
a.three = a.card2[i];
}
if (a.card2[i] == a.card2[i + 3]) {
a.four = a.card2[i];
}
}
for (i = 0; i < 4; i++) {
if (a.card2[i] == a.card2[i + 1]) {
a.two2 = a.card2[i];
break;
}
}
if (a.four != 0) {
a.level = 6;
a.score += a.four * 100 - 4 * a.four;
}
else if (a.three != 0 && a.two1 != a.two2) {
a.level = 5;
a.score += a.three * 100 - 3*a.three;
}
else if (a.three != 0&&a.two1==a.two2) {
a.level = 4;
a.score += a.three * 100 - 3 * a.three;
}
else if (a.two1 != a.two2) {
a.level = 3;
a.score += a.two1 * 10000 + a.two2 * 100 - 2 * a.two1 - 2 * a.two2;
}
else if (a.two1 != 0) {
a.level = 2;
a.score += a.two1 * 100 - a.two1 * 2;
}
else if (a.card2[0] == 1 && a.card2[1] == 10 && a.card2[2] == 11 && a.card2[3] == 12 && a.card2[4] == 13) {
a.level = 8;
}
else if (a.card2[1]==a.card2[0]+1&& a.card2[2] == a.card2[1] + 1 && a.card2[3] == a.card2[2] + 1 && a.card2[4] == a.card2[3] + 1 ) {
a.level = 7;
}
man[x].level = a.level;
man[x].score = a.score;
}/*分类判断各种牌型,并计算对应的分值*/
bool cmp(member x, member y)
{
if (x.level != y.level) return x.level > y.level;
if (x.score != y.score) return x.score > y.score;
return strcmp(x.name, y.name)<0;
}/*功能:按牌型、分值、姓名非升序排序*/
int main()
{
int N, i, j = 0;
scanf("%d", &N);
for (i = 0; i < N; i++) {
scanf("%s%s", man[i].name, man[i].card1);
convert(man[i].card1, man[i].card2);/*转换牌面*/
sort(man[i].card2, man[i].card2+5);/*对每一副牌的牌面非升序排序*/
judge(man[i],i);/*分类判断各种牌型,并计算对应的分值*/
}
sort(man, man+N, cmp);/*按牌型、分值、姓名非升序排序*/
for (i = 0; i < N; i++) {
puts(man[i].name);
}
return 0;
}
本题的关键在于分类判断各种牌型,而分类的前提是“读懂规则”。在我看来,运用纸笔或者记事本将题目规则理解透彻,应该是第一步。
复杂的规则下,本题需要的代码量较多,对各种牌型的判断容易出现交叉错误。可以尝试对程序进行分块化处理,分成不相关的几个模块,进而对各个模块逐一突破。
在测试数据的方面,可以考虑自己写测试数据。以不同等级下不同牌面为例,测试时输出对应的等级与分值,就可以直观地看出问题所在,返回该模块进行修改。
附:
粘贴代码到 word 的在线工具:PlanetB
使用教程->如何优雅的在 Microsoft word 中插入代码
原文:https://www.cnblogs.com/dump16/p/12397008.html