题目描述
瑞神HRZ因为疫情在家闲得无聊,同时他又非常厉害,所有的课对他来说都是水一水就能拿A+,所以他无聊,找来了另外三个人:咕咕东,腾神以及zjm来打牌(天下苦瑞神久矣)。
显然,牌局由四个人构成,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成。开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。
输入
输出多组数据发牌的结果,每组数据之后需要额外多输出一个空行!!!!! 每组数据应该由24行的组成,输出按照顺时针方向,始终先输出South Player的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。 |
输出
根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。 |
样例输入
样例输出
思路
综述
该题涉及到的知识:
1)多关键字排序
对于多关键字排序的题目,可以构造结构体P,重载小于号,再构造优先队列priority_queue<P>,从而达到排序的目的;
2)map的利用
因为不同的花色,代表的大小不同,但是代表花色的字母代号并不是按照ASCII码顺序排列,(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)所以可以如下操作:
map<char,int> mp;
mp['C'] = 1;
mp['D'] = 2;
mp['S'] = 3;
mp['H'] = 4;
对于牌号码的大小也相同:2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A
mp['2'] = 1;
mp['3'] = 2;
mp['4'] = 3;
mp['5'] = 4;
mp['6'] = 5;
mp['7'] = 6;
mp['8'] = 7;
mp['9'] = 8;
mp['T'] = 9;
mp['J'] = 10;
mp['Q'] = 11;
mp['K'] = 12;
mp['A'] = 13;
过程
结构体:
struct P {
char card;//花色
char value;//数值
bool operator < (const P &p)const{
if(card!=p.card) return mp[card]>mp[p.card];//先按照花色排序
return mp[value]>mp[p.value];//再按照数值排序
}
};
step1:
接收发牌人,记录其编号
cin>>x;
int first;
for(i=0;i<=3;i++)
if(mp2[i]==x) first = i;
step2:
接收所有牌,并且分发给四个人
四个人的牌存在优先队列数组内:priority_queue<P> pai[4];
fapai(int):记录下一张牌应发的人
string s1,s2;
cin>>s1>>s2;
s1+=s2;
int fapai = (first+1)%4;//从发牌人下一个开始
P nextcard;
for(i=0;i<s1.size();i++){
nextcard.card = s1[i];
nextcard.value = s1[++i];
pai[fapai].push(nextcard);
fapai=(fapai+1) % 4;//构成循环
}
step3:
输出
因为每一个优先队列已经按顺序排好,所以只需要顺序输出即可
对每个人:
分三波:牌号–>花色->牌号
构造结构体数组
struct P term[13];
第一次输出牌号的时候,顺便记录所有牌,第二三次顺序输出即可;
出现的小问题
一
sizeof和strlen的应用
- strlen() 时函数,他在程序运行时才能计算。它的参数类型要求时 char *,且必须是以’/0’结尾。数组在传入时已经退化为指针。它的作用是返回数组中字符串的长度。
- sizeof()时运算符,它在程序编译时就已经计算好了,用于计算数据空间的字节数。所以它不能用于返回动态分配的内存空间大小,常用于静态分配的类型,对象,结构或数组所占的空间。返回值和他们所存储的内容没有关系。
下图是dev中的输出:
下三图是VS中的输出:
所以,strlen()来求解字符数组,并不是很好的选择。
二
因为优先队列输出完后,为空。不能再从头输出一遍。但是如果再构造一个优先队列,采用复制构造函数。这样虽然可以正确输出,但是时间复杂度高,结果是超时;
所以,构造了一个结构体数组,这样后两遍便不需要再构造优先队列。
代码
#include <iostream>
#include <map>
#include <queue>
#include <string>
using namespace std;
map<char,int> mp;
struct P {
char card;
char value;
bool operator < (const P &p)const{
if(card!=p.card) return mp[card]>mp[p.card];
return mp[value]>mp[p.value];
}
};
int main(){
map<int,char> mp2;
mp2[0]='N';
mp2[1]='E';
mp2[2]='S';
mp2[3]='W';
mp['C'] = 1;
mp['D'] = 2;
mp['S'] = 3;
mp['H'] = 4;
mp['2'] = 1;
mp['3'] = 2;
mp['4'] = 3;
mp['5'] = 4;
mp['6'] = 5;
mp['7'] = 6;
mp['8'] = 7;
mp['9'] = 8;
mp['T'] = 9;
mp['J'] = 10;
mp['Q'] = 11;
mp['K'] = 12;
mp['A'] = 13;
int n,i,j,k;
char x;
priority_queue<P> pai[4];
while(1){
cin>>x;
if(x=='#')break;
int first;
for(i=0;i<=3;i++)
if(mp2[i]==x) first = i;
string s1,s2;
cin>>s1>>s2;
s1+=s2;
int fapai = (first+1)%4;
P nextcard;
for(i=0;i<s1.size();i++){
nextcard.card = s1[i];
nextcard.value = s1[++i];
pai[fapai].push(nextcard);
fapai=(fapai+1) % 4;
}
// 输出
P term[13];
int sx;
cout<<"South player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[2].top().card;
term[sx].value = pai[2].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[2].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"West player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[3].top().card;
term[sx].value = pai[3].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[3].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"North player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[0].top().card;
term[sx].value = pai[0].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[0].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"East player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[1].top().card;
term[sx].value = pai[1].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[1].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<endl;
}
}