题意:
input:
output:
对于每组测试数据,输出 n 行,即这次全场人的排名。
样例:
思路:
很明显是根据不同的牌的组合来得到一个分数,然后根据这个分数来进行一个关键字排序。在此处将关键字排序分为了三个:第一个关键字是手牌的8个类型,即按照给的手牌的分数,来依次给其score1赋上1到8分。第二个关键字是当手牌类型相同的时候,后续牌的大小不同来依次赋上score2相应的分数,例如对子中,首先比较对子大小,如果相同,即再比较剩下的三张牌的总和。在这里一开始考虑的是分情况讨论,想了挺久,觉得后期再总的排序有点麻烦,就给每个不同的重要性一个相应的权值。例如对子中,先比较对子大小,就先给对子的数值权值为100,乘上对子的牌的大小,后续的权值为1,这样权值大的有绝对的影响力。只有当前序的所有点都是一样的时候,后续的点才会起作用,对应上了比较的前后顺序,在这里给的每一阶权值都是100倍。第三个关键字即为姓名的字典序,可用string直接比较。
前期准备:一个1-13的数组tmp,分别记录5张牌有多少,然后tmp2记录是哪个五张牌,其中tot为牌种类数。根据牌的种类数,和每种牌有多少,可以依次得到属于哪一类,并根据数值,为其赋上相应的score1和score2。其中每个人的两个得分,手牌,姓名等,都是在结构体中,并重写了<,即可用sort进行排序,然后输出姓名即可。
代码:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int n;
priority_queue<int> Que;
int tmp[14]; //存放牌的种类
int tmp2[5]; //存放手牌的种类
int tot;
struct P{
int score1, score2;
string pai,name;
bool operator<(const P &p) const{
if(score1!=p.score1) return score1>p.score1;
if(score2!=p.score2) return score2>p.score2;
return name<p.name;
}
}Ps[100010];
int f(int t){
memset(tmp,0,sizeof(tmp));
memset(tmp2,0,sizeof(tmp2));
tot=0;
for(int i=0; i<Ps[t].pai.size(); i++){
if(Ps[t].pai[i]=='A'){ //65
tmp[1]++;
}else if(Ps[t].pai[i]=='1'){ //49
tmp[10]++;
}else if(Ps[t].pai[i]=='J'){ //74
tmp[11]++;
}else if(Ps[t].pai[i]=='Q'){ //81
tmp[12]++;
}else if(Ps[t].pai[i]=='K'){ //75
tmp[13]++;
}else{
tmp[Ps[t].pai[i]-48]++;
}
}
for(int i=1; i<=13; i++){
if(tmp[i]!=0) {
tmp2[tot]=i; //记录了有哪些牌
tot++;
}
}
int a=0;
if(tot==5){ //五种牌
int N=0;
int ret=-1;
for(int i=0; i<4; i++){
if(tmp2[i+1]!=tmp2[i]+1){
ret=1;
}
}
if(ret==-1){
Ps[t].score1=7; //顺子
Ps[t].score2=tmp2[4];
N=1;
}
if(N==0){
if(tmp2[0]==1){
int ret=-1;
for(int i=1; i<=4;i++){ //龙顺
if(tmp2[i]!=10+i-1){
ret=1;
}
}
if(ret==-1){
Ps[t].score1=8;
Ps[t].score2=0;
N=1;
}
}
}
if(N==0){ //大牌
Ps[t].score1=1;
for(int i=0; i<5; i++){
Ps[t].score2+=tmp2[i];
}
}
}else if(tot==4){ //对子
Ps[t].score1=2;
for(int i=0; i<=3; i++){
if(tmp[tmp2[i]]==2){
Ps[t].score2+=tmp2[i]*100;
}else{
Ps[t].score2+=tmp2[i];
}
}
}else if(tot==3){
int M=0;
for(int i=0; i<3; i++){
if(M<tmp[tmp2[i]]) M=tmp[tmp2[i]];
}
if(M==2){ //两对
Ps[t].score1=3;
int j=100;
for(int i=0; i<3;i++){
if(tmp[tmp2[i]]==1){
Ps[t].score2+=tmp2[i];
}else{
Ps[t].score2+=tmp2[i]*j;
j*=100;
}
}
}else{ //三个
Ps[t].score1=4;
for(int i=0; i<3;i++){
if(tmp[tmp2[i]]==1){
Ps[t].score2+=tmp2[i];
}else{
Ps[t].score2+=tmp2[i]*100;
}
}
}
}else{
int M=0;
for(int i=0; i<2; i++){
if(M<tmp[tmp2[i]]) M=tmp[tmp2[i]];
}
if(M==4){ /
Ps[t].score1=6;
for(int i=0; i<2; i++){
if(tmp[tmp2[i]]==4){
Ps[t].score2+=tmp2[i]*100;
}else{
Ps[t].score2+=tmp2[i];
}
}
}else{ //三带二
Ps[t].score1=5;
for(int i=0; i<2; i++){
if(tmp[tmp2[i]]==3){
Ps[t].score2+=tmp2[i]*100;
}else{
Ps[t].score2+=tmp2[i];
}
}
}
}
}
int main(){
ios::sync_with_stdio(0);
while(cin>>n){
for(int i=0; i<n; i++){
cin>>Ps[i].name>>Ps[i].pai;
f(i); //记录score1和score2
}
sort(Ps,Ps+n);
for(int i=0; i<n;i++){
cout<<Ps[i].name<<endl;
}
}
return 0;
}