B-东东学打牌

  • 题目描述
  • Input
  • Output
  • 解题思路
  • 实现代码
  • 总结

题目描述

打牌,只考虑牌的数值,不考虑花色,每个人五张手牌,每种牌数量无限,手牌大小比较规则:

序号越大,牌越大,在得知全场人手牌的情况下,按照手牌的大小,升序输出一个排行榜,牌大小相同时,名字字典序小的在前。

Input

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

Output

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

解题思路

1.建立合适的结构体用于存储每个人的手牌和姓名信息;
2.读入字符串,一行一个人,将手牌的字符串形式转换为整数形式,易于比较;
3.根据题目要求,判断牌型大小,先判断顺子、龙顺和大牌,因为这三种是没有相同的点数的;再根据相同点数的牌的数量,依次判断牌型,这里判断时,我提前对手牌进行了一次排序,这样在判断时思路会更清晰,不容易漏掉情况,具体的手牌判断形式见代码注释;
4.最后根据手牌牌型的大小关系定义重载比较符号,再利用sort排序,输出即可。

实现代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;struct Card
{string name,s2;int c[5];int dui,dui2[2],san,san2[2],boom,shun,dro_shun,last;Card();void change();void judge();bool operator<(const Card &p) const;
};Card::Card()
{dui=0;dui2[0]=0;dui2[1]=0;san=0;san2[0]=0;san2[1]=0;boom=0;shun=0;dro_shun=0;last=0;
}void Card::change()
{int index=0;for(int i=0;i<s2.size();++i){if(s2[i]=='A'){c[index]=1;index++;}else if(s2[i]=='1'){c[index]=10;index++;i++;}else if(s2[i]=='J'){c[index]=11;index++;}else if(s2[i]=='Q'){c[index]=12;index++;}else if(s2[i]=='K'){c[index]=13;index++;}else{c[index]=s2[i]-'0';index++;}}
}void Card::judge()
{sort(c,c+5);if((c[1]+1==c[2])&&(c[2]+1==c[3])&&(c[3]+1==c[4])){//后四张顺 if(c[0]+1==c[1])shun=c[4];     //常规顺子 else if(c[4]==13&&c[0]==1)dro_shun=1;       //龙顺 else if(c[0]==c[1]){dui=c[0];last=c[2]+c[3]+c[4];}elselast=c[0]+c[1]+c[2]+c[3]+c[4];}else{if(c[0]==c[1]){//已经有两张一样的 if(c[1]==c[2]){//已经有三张一样的 if(c[2]==c[3]){//四张一样,炸弹boom=c[0];last=c[4]; }else if(c[3]==c[4]){//c[0]=c[1]=c[2]<c[3]=c[4],三带一对 san2[0]=c[0];san2[1]=c[3];}else{//c[0]=c[1]=c[2]<c[3]<c[4],三张 san=c[0];last=c[3]+c[4];}}else if(c[2]==c[3]){//现在是两对 if(c[3]==c[4]){//c[0]=c[1]<c[2]=c[3]=c[4],三带一对 san2[0]=c[2];san2[1]=c[0];}else{//c[0]=c[1]<c[2]=c[3]<c[4],两对 dui2[0]=c[0];dui2[1]=c[2];last=c[4];}}else if(c[3]==c[4]){//c[0]=c[1]<c[2]<c[3]=c[4],两对 dui2[0]=c[0];dui2[1]=c[3];last=c[2]; }else{//c[0]=c[1]<c[2]<c[3]<c[4],一对 dui=c[0];last=c[2]+c[3]+c[4];}}else if(c[1]==c[2]){//两张一样的 if(c[2]==c[3]){//三张一样的 if(c[3]==c[4]){//c[0]<c[1]=c[2]=c[3]=c[4],炸弹 boom=c[1];last=c[0]; }else{//c[0]<c[1]=c[2]=c[3]<c[4],三张 san=c[1];last=c[0]+c[4];}}else if(c[3]==c[4]){//c[0]<c[1]=c[2]<c[3]=c[4],两对 dui2[0]=c[1];dui2[1]=c[3];last=c[0]; }else{//c[0]<c[1]=c[2]<c[3]<c[4],一对 dui=c[1];last=c[0]+c[3]+c[4];}}else if(c[2]==c[3]){//两张一样的 if(c[3]==c[4]){//c[0]<c[1]<c[2]=c[3]=c[4],三张 san=c[2];last=c[0]+c[1]; }else{//c[0]<c[1]<c[2]=c[3]<c[4],一对 dui=c[2];last=c[0]+c[1]+c[4];}}else if(c[3]==c[4]){//c[0]<c[1]<c[2]<c[3]=c[4],一对 dui=c[3];last=c[0]+c[1]+c[2];}else{//c[0]<c[1]<c[2]<c[3]<c[4],大牌 last=c[0]+c[1]+c[2]+c[3]+c[4]; }}
}bool Card::operator<(const Card &p) const
{if(dro_shun||p.dro_shun){if(dro_shun!=p.dro_shun)return dro_shun>p.dro_shun;elsereturn name<p.name;}if(shun||p.shun){if(shun!=p.shun)return shun>p.shun;elsereturn name<p.name;}if(boom||p.boom){if(boom!=p.boom)return boom>p.boom;else if(last!=p.last)return last>p.last;elsereturn name<p.name;}if(san2[0]||p.san2[0]){if(san2[0]!=p.san2[0])return san2[0]>p.san2[0];else if(san2[1]!=p.san2[1])return san2[1]>p.san2[1];elsereturn name<p.name;}if(san||p.san){if(san!=p.san)return san>p.san;else if(last!=p.last)return last>p.last;elsereturn name<p.name;}if(dui2[1]||p.dui2[1]){if(dui2[1]!=p.dui2[1])return dui2[1]>p.dui2[1];else if(dui2[0]!=p.dui2[0])return dui2[0]>p.dui2[0];else if(last!=p.last)return last>p.last;else return name<p.name;}if(dui||p.dui){if(dui!=p.dui)return dui>p.dui;else if(last!=p.last)return last>p.last;elsereturn name<p.name;}if(last||p.last){if(last!=p.last)return last>p.last;elsereturn name<p.name;}
}Card p[100010];int main()
{int n;cin>>n;for(int i=0;i<n;++i){cin>>p[i].name>>p[i].s2;p[i].change();p[i].judge();}sort(p,p+n);for(int i=0;i<n;++i)cout<<p[i].name<<endl;return 0;
}

总结

本题思路与Week6的模拟是类似的,主要用合理的结构体来存储牌型信息,最重要的是合理的对牌型进行判断,剩下的就很简单了(除了比较费时间之外)。
这种题目思路要清晰,像牌型判断这里,写的要有层次逻辑,要不然容易漏掉情况,debug还会很折磨。

程序设计Week9——B-东东学打牌相关推荐

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

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

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

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

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

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

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

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

  5. 程序设计思维 B - 东东学打牌

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

  6. [week9]东东学打牌

    文章目录 题意 Input Output 输入样例 输出样例 提示 分析 总结 代码 题意 最近,东东沉迷于打牌.所以他找到 HRZ.ZJM 等人和他一起打牌.由于人数众多,东东稍微修改了亿下游戏规则 ...

  7. Week9 作业——B - 东东学打牌

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

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

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

  9. week9 B-东东学打牌

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

最新文章

  1. java web 调用hadoop_Java及Web程序调用hadoop2.6
  2. laravel5.6 Session
  3. 易天教你如何保养SFP光模块
  4. DDR3 LAYOUT RULES
  5. 在Xcode8中 如何添加.pch文件
  6. 为了建设我们的飞鸽传书2011
  7. php mysql 一级分类_无限级分类 for PHP+Mysql
  8. 5-顺序表查找及插入问题
  9. java armeabi_armeabi和armeabi-v7a 解释
  10. lintcode--报数
  11. vs编译与停止调试时卡顿、无响应的问题
  12. 总结 | C#实现Excel导出功能
  13. python中string什么意思_Python:string是什么意思
  14. Saliency Filter
  15. PHPStorm 显示自动换行
  16. 常用的70个数据分析网址
  17. BGP高防服务器是什么?要怎么选?
  18. 微软2013暑假实习生笔试题
  19. 为什么要构建知识体系?
  20. live555源码分析----关于mp3的处理

热门文章

  1. 华纳云:香港机房基础网络架构
  2. 修改 Outlook 数据文件默认保存位置
  3. 关于pegeoffice插件 文件模板使用分页符 用word打开独占一页问题解决方式
  4. Element ui中如何对el-select进行失焦校验
  5. 苹果面临集体诉讼 因涉嫌销售iTunes和Apple Music用户数据
  6. 非controller层调用service2种
  7. 大雁塔尺寸_仅用一张A4纸和计算器针对西安大雁塔高度的测量
  8. 别玩手机了,你没时间了!
  9. mdx java_MDX大部分常用函数
  10. 算法思想简介(分制(分开在递归),贪心(DJS),动态分配(dp,解决多变化条件),回溯(万能,深度优先))