C - 瑞神打牌 (不支持C++11;G++和C++编译器都试试!)
题目描述
瑞神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。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。
Input
输入包含多组数据
每组数据的第一行包含一个大写字符,表示发牌员是谁。如果该字符为‘#’则表示输入结束。
接下来有两行,每行有52个字符,表示了26张牌,两行加起来一共52张牌。每张牌都由两个字符组成,第一个字符表示花色,第二个字符表示数值。
Output
输出多组数据发牌的结果,每组数据之后需要额外多输出一个空行!!!!!
每组数据应该由24行的组成,输出按照顺时针方向,始终先输出South Player的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。
Sample Input
N
CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9
SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3
#
Sample Output
South player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T|
| C | C | D | D | S | S | S | S | H | H | H | H | H |
|6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
West player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A|
| C | C | C | C | D | D | D | S | S | S | S | H | H |
|2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
North player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3|
| C | C | C | D | D | D | D | D | S | S | S | H | H |
|3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
East player:
+---+---+---+---+---+---+---+---+---+---+---+---+---+
|7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K|
| C | C | C | C | D | D | D | S | S | H | H | H | H |
|7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K|
+---+---+---+---+---+---+---+---+---+---+---+---+---+
思路
1,开特殊数组真香,尤其是题目中给的特殊集和,函数orderOfchar(char a,string p)返回a在字符串string中的序号,便于后续重写卡片结构体排序与输出。
string Shape="CDSH";
string Num="23456789TJQKA";
string Player="NESW";
string name[4]={"North player:","East player:",
"South player:","West player:"};
int orderOfchar(char a,string p){//字母的排序序号
for(int i=0; i<p.size(); i++){
if(a == p[i]){
return i;
break;
}
}
}
2,多关键字排序,利用结构体,重写排序函数;
bool cmp(Card p1,Card p2){//卡片比较:
int s1=orderOfchar(p1.shape,Shape);
int s2=orderOfchar(p2.shape,Shape);
int n1=orderOfchar(p1.num,Num);
int n2=orderOfchar(p2.num,Num);
if(s1 == s2)
return n1<n2;
else return s1<s2;
}
3,memset(index, 0, 4* sizeof(int))的头文件 string.h,cout<< oj编译报错记得加string.h
4, 对于输入输出控制,类似于B题,一串字符串读入可以采取一边读入一遍处理的思路,这样流程简单明了
5,first为发牌人物的序号,sp记录第一副牌是 name[4]中第几个人的牌,输出时通过加循环变量i再模4便可输出对应卡牌次序。
int first=orderOfchar(player,Player);//第一个人的位置
int Sp;//South玩家是第几份牌;
if(first==0) Sp=1;
else if(first==1) Sp=0;
else if(first==2) Sp=3;
else if(first==3) Sp=2;
6,**尽量使代码模块化,框架结构明晰,**那一块实现什么功能要清除,一定要清除自己想干什么;
7,输出中的单词不要打错,题中给的就直接复制过来,以图片形式给出的一定注意拼写!
8,严格按照题目中output中要求的格式输出!
代码
#include<iostream>
#include<string.h>
#include<string>
#include<cmath>
#include<iomanip>
#include<algorithm>
/*
卡片游戏
*/
using namespace std;
struct Card{//卡片的结构体
char shape;
char num;
};
string Shape="CDSH";
string Num="23456789TJQKA";
string Player="NESW";
string name[4]={"North player:","East player:",
"South player:","West player:"};
int orderOfchar(char a,string p){//字母的排序序号
for(int i=0; i<p.size(); i++){
if(a == p[i]){
return i;
break;
}
}
}
bool cmp(Card p1,Card p2){//卡片比较:
int s1=orderOfchar(p1.shape,Shape);
int s2=orderOfchar(p2.shape,Shape);
int n1=orderOfchar(p1.num,Num);
int n2=orderOfchar(p2.num,Num);
if(s1 == s2)
return n1<n2;
else return s1<s2;
}
int main()
{
Card card[4][13];//4*13=52张牌;
char player;
char theShape,theNum;
int index[4];
while(1)
{
cin>>player;
if(player == '#')break;
memset(index, 0, 4* sizeof(int));
for(int i=0; i<52; i++)
{//输入52张牌;
cin>>theShape>>theNum;
card[i%4][ index[i%4] ].shape=theShape;
card[i%4][ index[i%4]++ ].num=theNum;
}
for(int i=0; i<4; i++)
sort(card[i],card[i]+13,cmp);
int first=orderOfchar(player,Player);//第一个人的位置;
int Sp;//South玩家是第几份牌;
if(first==0) Sp=1;
else if(first==1) Sp=0;
else if(first==2) Sp=3;
else if(first==3) Sp=2;
for(int i=0; i<4; i++)
{//结果输出;
int theIndex=(Sp+i)%4;//
cout<<name[(2+i)%4]<<endl;//第一行名字
for(int j=0; j<13; j++){ //第1行
if(j==12)cout<<"+---+"<<endl;
else cout<<"+---";
}
for(int j=0; j<13; j++){//第2行
if(j==12)cout<<'|'<<card[theIndex][j].num<<' '<<card[theIndex][j].num<<'|'<<endl;
else cout<<'|'<<card[theIndex][j].num<<' '<<card[theIndex][j].num;
}
for(int j=0; j<13; j++){//第3行
if(j==12)cout<<'|'<<' '<<card[theIndex][j].shape<<' '<<'|'<<endl;
else cout<<'|'<<' '<<card[theIndex][j].shape<<' ';
}
for(int j=0; j<13; j++){//第4行
if(j==12)cout<<'|'<<card[theIndex][j].num<<' '<<card[theIndex][j].num<<'|'<<endl;
else cout<<'|'<<card[theIndex][j].num<<' '<<card[theIndex][j].num;
}
for(int j=0; j<13; j++){//第5行
if(j==12)cout<<"+---+"<<endl;
else cout<<"+---";
}
}
cout<<endl;
}
return 0;
}