题目

最近,东东沉迷于打牌。所以他找到 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 张牌不同,其值不同。下面依次列举了这手牌的形成规则:

大牌:这手牌不符合下面任一个形成规则。如果 α 和 β 都是大牌,那么定义它们的大小为组成这手牌的 5 张牌的大小总和。
对子:5 张牌中有 2 张牌的值相等。如果 α 和 β 都是对子,比较这个 “对子” 的大小,如果 α 和 β 的 “对子” 大小相等,那么比较剩下 3 张牌的总和。
两对:5 张牌中有两个不同的对子。如果 α 和 β 都是两对,先比较双方较大的那个对子,如果相等,再比较双方较小的那个对子,如果还相等,只能比较 5 张牌中的最后那张牌组不成对子的牌。
三个:5 张牌中有 3 张牌的值相等。如果 α 和 β 都是 “三个”,比较这个 “三个” 的大小,如果 α 和 β 的 “三个” 大小相等,那么比较剩下 2 张牌的总和。
三带二:5 张牌中有 3 张牌的值相等,另外 2 张牌值也相等。如果 α 和 β 都是 “三带二”,先比较它们的 “三个” 的大小,如果相等,再比较 “对子” 的大小。
炸弹:5 张牌中有 4 张牌的值相等。如果 α 和 β 都是 “炸弹”,比较 “炸弹” 的大小,如果相等,比较剩下那张牌的大小。
顺子:5 张牌中形成 x, x+1, x+2, x+3, x+4。如果 α 和 β 都是 “顺子”,直接比较两个顺子的最大值。
龙顺: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

思路

数据结构

int cnt[14]:存储每个成员手里的牌牌面数字的个数
int num[5]:存储成员中单张牌的牌面数字
int num_cnt[6]:存储成员不同个数牌的个数
struct player:存储每个成员的姓名、牌、牌的类型、牌中呈对、三张、四张的牌的牌面的数字和手中牌面数字之和
{char name[20];
// string name;int pai[5];int type;int duizi[2]={0,0};int sum; bool operator<(const player &p) const 重载比较符,先比较type,在type相等时,再按顺序比较存储在duizi中的数其中当为两对的情况时,duizi[0]存储两对中较大的,duizi[1]中存储为两对中较小的当为三代二:duizi[0]为3个的数字,duizi[1]为2个的数字当为三个和炸弹时:duizi[0]存储三个或四个的数字,duizi[1]=0在其他情况时:duizi[0/1]=0当duizi都相等时,根据题意的各个比较都可以转化为比较所有牌面总和当牌面总和也相等时,说明两个player手中的牌相同,所以直接比较名字的字典序即可得到排名{if(type!=p.type)return type>p.type;if(duizi[0]!=p.duizi[0])return duizi[0]>p.duizi[0];if(duizi[1]!=p.duizi[1])return duizi[1]>p.duizi[1];if(sum!=p.sum)return sum>p.sum;//为啥反了???? int l1=strlen(name),l2=strlen(p.name);for(int j=0;j<min(l1,l2);j++){if(name[j]==p.name[j]) continue;if(name[j]<p.name[j]) return true;if(name[j]>p.name[j]) return false;}if(l1<l2) return true;return false;
//  return name<p.name; }
}p[maxn]

解法

1、对每一个新队员,先将该队员对应的p[i]内的所有内容初始化,再录入姓名到name中,牌面到临时字符串容器中,将其处理成数字并储存到p中,同时计算每个牌面数字的个数存储到cnt中
2、从小到大遍历cnt数组,计算不同个数的数字的个数存储到num_cnt中,将单张牌存储到num中,同时针对不同的cnt更新type
3、判断牌是否是顺子或龙顺并更新type
4、调用sort,按从大到小排序并按排名输出。

错误

1、谁能想到把龙顺以为成从10开始连续的五张牌这个脑残的错误我能调一周???orz
2、注意当用char[20]存储名字的时候,调用return name<p.name时HRZ和ZJM的排序会反过来,所以考虑自己实现字典序的比较,如下:

  //为啥反了???? int l1=strlen(name),l2=strlen(p.name);for(int j=0;j<min(l1,l2);j++){if(name[j]==p.name[j]) continue;if(name[j]<p.name[j]) return true;if(name[j]>p.name[j]) return false;}if(l1<l2) return true;return false;
//  return name<p.name; }
}p[maxn]

但是当名字用string类型存储时,return name<p.name得到的就是按照字典序排序的名字
3、一开始忘记对新一组的数据duizi置为空值
4、注意在进入判断该成员的牌的类型之前先将牌的类型置为1,之后仅对牌更高一级的情况再更新牌的类型
5、五张牌都相等的情况也是炸弹

代码

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;
const int maxn=1e5+10;
const int maxm=20;
int cnt[14];
int num[5];
int num_cnt[6];
int tmp_sum=0;
struct player
{char name[20];
//  string name;int pai[5];int type;int duizi[2]={0,0};int sum;    bool operator<(const player &p) const{if(type!=p.type)return type>p.type;if(duizi[0]!=p.duizi[0])return duizi[0]>p.duizi[0];if(duizi[1]!=p.duizi[1])return duizi[1]>p.duizi[1];if(sum!=p.sum)return sum>p.sum;//为啥反了???? int l1=strlen(name),l2=strlen(p.name);for(int j=0;j<min(l1,l2);j++){if(name[j]==p.name[j]) continue;if(name[j]<p.name[j]) return true;if(name[j]>p.name[j]) return false;}if(l1<l2) return true;return false;
//      return name<p.name; }
}p[maxn];
int main()
{int n;char temp_pai[20];while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++)//i为第i个人的牌 {cin>>p[i].name;cin>>temp_pai;p[i].duizi[0]=0;//注意每次需将p中所有的值置为初值 p[i].duizi[1]=0;int j=0;int m=0;//初始化 p[i].sum=0;//初始化 memset(cnt,0,sizeof(cnt));while(temp_pai[j]!='\0'){if(temp_pai[j]=='A'){p[i].pai[m]=1;p[i].sum+=1;cnt[1]++;                   }else if(temp_pai[j]=='J'){p[i].pai[m]=11;p[i].sum+=11;//直接更新该player的sum cnt[11]++;                    }else if(temp_pai[j]=='Q'){p[i].pai[m]=12; p[i].sum+=12;cnt[12]++;             }else if(temp_pai[j]=='K'){p[i].pai[m]=13; p[i].sum+=13;cnt[13]++;             }else if(temp_pai[j]=='1'){p[i].pai[m]=10;p[i].sum+=10;cnt[10]++;j++;}else{int tmp=temp_pai[j]-'0';p[i].pai[m]=tmp;p[i].sum+=tmp;cnt[tmp]++;             }j++;m++;}m=0;//单张牌的个数 int x=0;//对子的个数 memset(num,0,sizeof(num));//存储仅有一张的牌 memset(num_cnt,0,sizeof(num_cnt));
//          cout<<"cnt:"<<endl;
//          for(j=0;j<14;j++)
//              cout<<cnt[j]<<' ';
//          cout<<endl;           p[i].type=1;//将初始情况置为1,因为后面可能出现五张牌都相等的情况 for(j=1;j<=13;j++){if(cnt[j]==1){num_cnt[1]++;num[m]=j;m++;}else if(cnt[j]==2){num_cnt[2]++;if(x==1){if(num_cnt[2]==2)//注意这里num_cnt已经加一了,故要判断是否==2 {p[i].duizi[1]=p[i].duizi[0];p[i].duizi[0]=j;p[i].type=3;                     }else if(num_cnt[3]==1){p[i].duizi[x]=j;p[i].type=5;}x++;}else{p[i].duizi[x]=j;p[i].type=2;                     }x++;             }else if(cnt[j]==3){num_cnt[3]++;if(x==1){p[i].duizi[1]=p[i].duizi[0];p[i].duizi[0]=j;p[i].type=5;}else{p[i].duizi[x]=j;p[i].type=4;                     } x++; }else if(cnt[j]==4||cnt[j]==5)//注意当五张牌都相等时,也是炸弹 {num_cnt[4]++;p[i].duizi[x]=j;p[i].type=6;x++;}   }
//          cout<<"num_cnt:"<<endl;
//          for(j=0;j<6;j++)
//              cout<<num_cnt[j]<<' ';
//          cout<<endl;
//          cout<<"num:"<<endl;
//          for(j=0;j<5;j++)
//              cout<<num[j]<<' ';
//          cout<<endl;if(num_cnt[1]==5){int flag=0;for(j=0;j<4;j++)if(num[j]!=num[j+1]-1)flag=1;if(flag==0){p[i].type=7;                  }else if(num[0]==1&&num[1]==10&&num[2]==11&&num[3]==12&&num[4]==13)//注意龙顺是10、j、q、k、a p[i].type=8;}   }sort(p,p+n);for(int i=0;i<n;i++){cout<<p[i].name<<endl;
//          for(int j=0;j<5;j++)
//              cout<<p[i].pai[j];
//          cout<<p[i].type<<' '<<p[i].duizi[0]<<' '<<p[i].duizi[1]<<' '<<p[i].sum;
//          cout<<endl;       }}return 0;
}

Week9 作业——B - 东东学打牌相关推荐

  1. 【Week9作业 B】东东学打牌【模拟】

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

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

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

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

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

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

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

  5. 东东学打牌 Week9作业B题

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

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

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

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

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

  8. [week9]东东学打牌

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

  9. week9 B-东东学打牌

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

最新文章

  1. 内存溢出和内存泄漏的区别、产生原因以及解决方案 转
  2. 命令测试post_性能测试脚本编写之三
  3. 云原生架构下的持续交付实践
  4. java 解析并生成 XML
  5. 朋友圈句句刺痛人心的唯美句子有哪些
  6. Python XML操作处理
  7. Servlet技术 - Servlet应用
  8. 后台运行shell命令eog,并用pkill关闭
  9. 华为数通模拟器ensp问题解决方法
  10. 阿里云域名解析成功后无法ping问题
  11. QingCloud Insight 2016 | 科技,洞见未来
  12. WDK10编译出最适合申请WHQL认证的驱动
  13. 北极寒流带来《后天》享受(组图)零下50度美国城市成灾区出门都犯法
  14. Minkowski不等式
  15. 农副产品视觉检测——大米外观品质检测仪
  16. CSS floats来创建三栏网页布局的方法
  17. 物联网发展的基石——传感器
  18. 换ip地址除开虚拟服务器,GoDaddy虚拟主机更换IP地址和更换主域名绑定的方法
  19. Maxwell 的使用
  20. u盘 ultraiso 安装centos7步骤(折腾了一天才安装成功)

热门文章

  1. win10百度网盘不限速(百度网盘直接下载助手 +油猴脚本)(2019.3.15更新)
  2. 微信小程序-体育场馆场地预约系统
  3. 公司、分公司、子公司、有限公司、企业、个体户的区别!
  4. java 私有类_Java类属性的私有化
  5. P2P网络ISIS的PSNP报文的两种用途
  6. webpack:package.json中scripts的作用
  7. 等保测评之安全区域边界
  8. Tomcat目录结构
  9. 金融经济学(王江)第四章 套利和资产定价
  10. git stash命令之暂存的操作