题目

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

  1. 所有扑克牌只按数字来算大小,忽略花色。
  2. 每张扑克牌的大小由一个值表示。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。
  3. 每个玩家抽得 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

思路

设值为A、2、···、10、J、Q、K的牌分别称为第1、2、···、10、11、12、13种牌。
设置一个数组times[14]:times[i] = k表示第i种牌出现了k次。
对于每个玩家,用times[]统计每种牌在五张牌中出现的次数。
然后用5个向量type[5]统计出现了0~4次的牌分别有哪些。例如,若type[2] = {2, 3},则说明第2种牌、第3种牌各都出现了2次。
接着有如下几种情况:

  1. 龙顺:times[10] = 1 且 times[11] = 1 且 times[12] = 1 且 times[13] = 1 且 times[1] = 1。
  2. 顺子:存在一i,使得times[i] = 1 且 times[i + 1] = 1 且 times[i + 2] = 1 且 times[i + 3] = 1 且 times[i + 4] = 1。
  3. 炸弹:type[4].size() != 0。
  4. 三带二:type[3].size() != 0 且 type[2].size() != 0。
  5. 三个:type[3].size() != 0 且 type[2].size() = 0。
  6. 两对:type[2].size() = 2。
  7. 对子:type[2].size() = 1。
  8. 大牌:type[2].size() = 0。

为了便于比较,对每个玩家的手牌进行打分,最后根据分值的高低进行排序。若有两个玩家的手牌分值相同,那么人名字典序小的排在前面。
而对手牌打分的规则为:

  1. 龙顺:score = 8 * MAX。
  2. 顺子:score = 7 * MAX + i + 4。
  3. 炸弹:score = 6 * MAX + type[4][0] * 100 + type[1][0]。
  4. 三带二:score = 5 * MAX + type[3][0] * 100 + type[2][0]。
  5. 三个:score = 4 * MAX + type[3][0] * 100 + type[1][0] + type[1][1]。
  6. 两对:score = 3 * MAX + max(type[2][0], type[2][1]) * 10000 + min(type[2][0], type[2][1]) * 100 + type[1][0]。
  7. 对子:score = 2 * MAX + type[2][0] * 100 + type[1][0] + type[1][1] + type[1][2]。
  8. 大牌:score = MAX + type[1][0] + type[1][1] + type[1][2] + type[1][3] + type[1][4]。

其中,MAX是一个特别大的数,这样就可以通过分值,即比较不同类型的手牌,又比较相同类型的手牌。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <stdio.h>#define MAX 1000000using namespace std;struct player {string name;string cards;int times[14] = { 0 }; //每张牌出现的次数,times[0]不用player(string theName, string theCards) : name(theName), cards(theCards) {}
};struct person {string name;int score;person(string theName, int theScore) : name(theName), score(theScore) {}//排序bool operator < (const person& p) const {if (score != p.score) { //按分数排序return score > p.score;}if (name.compare(p.name) < 0) { //按名字排序return true;}return false;}
};void sortCard(player& p)
{int ind = 0;while (p.cards[ind] != '\0') {char card = p.cards[ind];if ('2' <= card && card <= '9') p.times[card - '0']++;else if (card == '1') { p.times[10]++; ind++; }else if (card == 'A') p.times[1]++;else if (card == 'J') p.times[11]++;else if (card == 'Q') p.times[12]++;else if (card == 'K') p.times[13]++;ind++;}
}int caluculate(const player& p)
{//龙顺if (p.times[10] == 1 && p.times[11] == 1 && p.times[12] == 1 && p.times[13] == 1 && p.times[1] == 1)return 8 * MAX;//顺子for (int i = 1; i <= 9; i++)if (p.times[i] == 1 && p.times[i + 1] == 1 && p.times[i + 2] == 1 && p.times[i + 3] == 1 && p.times[i + 4] == 1)return 7 * MAX + i + 4;//统计每张牌出现的次数vector<int> type[5];for (int i = 1; i <= 13; i++)type[p.times[i]].push_back(i);//炸弹if (type[4].size() != 0)return 6 * MAX + type[4][0] * 100 + type[1][0];//三带二if (type[3].size() != 0 && type[2].size() != 0)return 5 * MAX + type[3][0] * 100 + type[2][0];//三个if (type[3].size() != 0 && type[2].size() == 0)return 4 * MAX + type[3][0] * 100 + type[1][0] + type[1][1];//两对if (type[2].size() == 2)return 3 * MAX + max(type[2][0], type[2][1]) * 10000 + min(type[2][0], type[2][1]) * 100 + type[1][0];//对子if (type[2].size() == 1)return 2 * MAX + type[2][0] * 100 + type[1][0] + type[1][1] + type[1][2];//大牌if (type[2].size() == 0)return MAX + type[1][0] + type[1][1] + type[1][2] + type[1][3] + type[1][4];
}int n;
list<person> persons;void init()
{persons.clear();
}int main()
{int n;while (scanf("%d", &n) != EOF) {getchar();init();for (int i = 0; i < n; i++) {string str;getline(cin, str);int pos = str.find(" ");string name = str.substr(0, pos);string cards = str.substr(pos + 1, str.size() - pos - 1);player p(name, cards);sortCard(p);int score = caluculate(p);person per(name, score);persons.push_back(per);}//排序persons.sort();for (list<person>::iterator it = persons.begin(); it != persons.end(); it++)cout << (*it).name << endl;}return 0;
}

程序设计思维 B - 东东学打牌相关推荐

  1. 山东大学计算机科学与技术学院程序设计思维与实践作业 week5-数学基础与线性结构

    山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践作业 sdu程序设计思维与实践 山东大学程序设计思维实践作业H5 山大程序设计思维实践作业H5 山东大学程序设计思维与实践 w ...

  2. 程序设计思维 week9 作业B-东东学打牌

    目录 题目 Input Ouput Sample Input Sample Ouput 思路 代码 总结 题目 所有扑克牌只按数字来算大小,忽略花色. 每张扑克牌的大小由一个值表示.A, 2, 3, ...

  3. 程序设计Week9——B-东东学打牌

    B-东东学打牌 题目描述 Input Output 解题思路 实现代码 总结 题目描述 打牌,只考虑牌的数值,不考虑花色,每个人五张手牌,每种牌数量无限,手牌大小比较规则: 序号越大,牌越大,在得知全 ...

  4. 程序设计之B - 东东学打牌(C++

    目录 题目 大致题意 解题分析 测试数据(全面 代码 题目 题面 最近,东东沉迷于打牌.所以他找到 HRZ.ZJM 等人和他一起打牌.由于人数众多,东东稍微修改了亿下游戏规则: 所有扑克牌只按数字来算 ...

  5. 【Week9 作业】A - 咕咕东的目录管理器、B - 东东学打牌、C - 签到题,独立思考哈

    A - 咕咕东的目录管理器 题意: 咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响,时不时发生故障,他受不了了,想要写一个高效易用零bug的操作系统 -- 这工程量太大了,所以他定了一个小目标, ...

  6. WEEK9 作业 B - 东东学打牌

    B - 东东学打牌 题目描述 最近,东东沉迷于打牌.所以他找到 HRZ.ZJM 等人和他一起打牌.由于人数众多,东东稍微修改了亿下游戏规则: 所有扑克牌只按数字来算大小,忽略花色. 每张扑克牌的大小由 ...

  7. SDU程序设计思维Week6-限时模拟 掌握魔法の东东II

    程序设计思维Week6-限时模拟 掌握魔法の东东II Description 东东有 A × B 张扑克牌.每张扑克牌有一个大小(整数,记为a,范围区间是 0 到 A - 1)和一个花色(整数,记为b ...

  8. B - 东东学打牌(Week9.2作业)

    题面 最近,东东沉迷于打牌.所以他找到 HRZ.ZJM 等人和他一起打牌.由于人数众多,东东稍微修改了亿下游戏规则: 所有扑克牌只按数字来算大小,忽略花色. 每张扑克牌的大小由一个值表示.A, 2, ...

  9. week9-东东学打牌

    问题描述: 最近,东东沉迷于打牌.所以他找到 HRZ.ZJM 等人和他一起打牌.由于人数众多,东东稍微修改了亿下游戏规则: 所有扑克牌只按数字来算大小,忽略花色. 每张扑克牌的大小由一个值表示.A, ...

最新文章

  1. conda不是内部或外部命令
  2. 自然语言处理NLP国内研究方向机构导师
  3. 是什么牌子_电暖气片什么牌子好
  4. SpringMVC源码阅读:过滤器
  5. Clojure语法学习-循环
  6. Linux网络编程——I/O复用之poll函数
  7. ubuntu 16.04 安装TensorFlow GPU版本
  8. 二叉链表存储的二叉C语言,C语言实现二叉链表存储
  9. win10磁盘管理_win10合并磁盘分区教程
  10. 连接共享打印机时,弹出无法安装打印机,打印处理器不存在!!
  11. Java【递归及过滤器】
  12. 什么是等保?为什么要做等保?
  13. 关于eclipse导入项目后架包找不到问题
  14. MYSQL命令大全自学笔记
  15. 智能窗帘不知选米家?还是Aqara?这些入坑前必备工作智汀来告诉你
  16. 阶段三 JavaScript网页编程---js基础语法
  17. 智能营销文本生成项目知识点总结
  18. 2048游戏制作html,一个自制的2048小游戏(一)
  19. 大数据产业驱动智慧家庭发展
  20. 有刷直流电机的工作原理及控制电路

热门文章

  1. MATLAB | 三个趣的圆相关的数理性质可视化
  2. 十大算法之弗洛伊德算法
  3. 快速入门Web阅读器开发
  4. MACD指标使用的一些小技巧
  5. 游戏存档破解、售卖的危害及解决办法
  6. JDK和tomcat配置HTTPS协议
  7. 如何制作全息视频--3D max+AE搞定
  8. 超简单集成HMS ML套件二代身份证识别,一键实名认证
  9. 萧乾升:3.25黄金白银TD实时最新行情走势分析
  10. 自动化测试框架: KIF和EarlGrey对比