原题叙述
题目叙述
瑞神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的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。
读入样例
N
CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9
SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3
#
输出样例
不知道为啥显示有点乱码,大概要求就是第一行是1,5,10后面都是5的偶数倍就输出一个“+”,其余输出“-”,最后以“+”作为结尾
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|
±–±--±–±--±–±--±–±--±–±--±–±--±–+
问题重述
四个方位坐定四个参与者,每个人的位置不再变化。每次输入一个方位,这个方位作为本次发牌员,他的顺时针方向下一个参与者作为发牌的起始位置。
备注顺时针方向是:
输入的两行字符串代表52张牌,每两个字符代表一张牌
两个字符中的第一个代表花色
规定花色的排行升序如下:
第二个字符代表牌面的大小
规定牌面的大小关系升序如下:
根据输入的位置和字符串,为每个人发牌,并按照上述的顺序输出相应形式的牌面
解题思路
思路概述
基本结构:
构造了一个person类来存储每个人手上的牌面、花色和所在方向,详细可见数据存储部分的表格
输入:
字符串的输入开了个两个string,拼接在一起然后遍历这个string依次将取出的字符添加到对应struct person里的牌面、花色数组即可。
输出:
仔细观察可以得知每个人的输入输出都是一个对称的形式,1,5相同,2,4相同,暴力写一下模拟,大不了输出调两边即可。
练习赛思路(×)
又是一道写上头了的题,上来先写的C题,想都没想什么重载运算符,直接在struct里存了一个value数组,然后把四种花色分别赋权(1,2,3,4),并从字符串中分别取出花色m权值和面值n,使用公式
value[i]=m*13+n
然后走火入魔的我居然又手写了一个排序函数,对value数组排了个序再依次输出,现在想想都后怕…
赛后思考(√)
这就根本不用什么手写排序,就重载一下运算符,然后按照花色第一关键字,牌面第二关键字,按照给定的顺序排序就好。这里时间紧促还没来得及实现,周末补题再修改下,博客也会把新代码加进来。
数据存储
为每个人开一个struct:
变量类型及变量名 | 变量的实际意义 |
---|---|
string pos | 该参与者的位置 |
string num | 牌的面值 |
string col | 牌的花色 |
int value[] | 使用赋权函数计算得到的排名依据 |
这里的value数组在改进过程中发现并无意义
总结
一个表面看起来输入输出很困难,看懂题意思考一下会发现蛮简单的题目,有的时候真的不是大力出奇迹,多思考再打代码效率会好很多。
改进点
由于上头代码写的冗余问题十分严重,后续补题尽量改进优化。另外由于实验期间一次map初始化的问题,直接使用了暴力枚举法进行一些函数的实现,在课后查询了相关的网站,修改版中会使用map高效的实现代码。
问题源码(初版)
#include<iostream>
#include<string>
#include<cstdio>
#include<map>
using namespace std;
struct person
{
string pos;
string num;
string col;
int value[20];
void give_value()
{
for (int i = 0; i < 20; i++)
{
value[i] = 0;
}
for (int i = 0; i < 13; i++)
{
int number = 0;
int colber = 0;
if (num[i] == '1') number = 1;
else if (num[i] == '2') number = 2;
else if (num[i] == '3') number = 3;
else if (num[i] == '4') number = 4;
else if (num[i] == '5') number = 5;
else if (num[i] == '6') number = 6;
else if (num[i] == '7') number = 7;
else if (num[i] == '8') number = 8;
else if (num[i] == '9') number = 9;
else if (num[i] == 'T') number = 10;
else if (num[i] == 'J') number = 11;
else if (num[i] == 'Q') number = 12;
else if (num[i] == 'K') number = 13;
else if (num[i] == 'A') number = 14;
if (col[i] == 'C') colber = 1;
else if (col[i] == 'D') colber = 2;
else if (col[i] == 'S') colber = 3;
else if (col[i] == 'H') colber = 4;
value[i] = 14 * colber + number;
}
}
void sort_person()
{
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 12-i; j++) {
if (value[j + 1] < value[j]) {
swap(value[j + 1], value[j]);
swap(col[j + 1], col[j]);
swap(num[j + 1], num[j]);
}
}
}
}
void print()
{
cout<<pos<<":"<<endl;
for(int i=0;i<52;i++)
{
if(i%4==0) cout<<"+";
else
cout<<"-";
}
cout<<"+"<<endl;
for(int i=0;i<13;i++)
{
cout<<"|"<<num[i]<<" "<<num[i];
}
cout<<"|"<<endl;
for(int i=0;i<13;i++)
{
cout<<"|"<<" "<<col[i]<<" ";
}
cout<<"|"<<endl;
for(int i=0;i<13;i++)
{
cout<<"|"<<num[i]<<" "<<num[i];
}
cout<<"|"<<endl;
for(int i=0;i<52;i++)
{
if(i%4==0) cout<<"+";
else
cout<<"-";
}
cout<<"+"<<endl;
}
};
int position(person* a, string pos)
{
if (pos == "E")
{
a[0].pos = "South player";
a[1].pos = "West player";
a[2].pos = "North player";
a[3].pos = "East player";
return 0;
}
else if (pos == "S")
{
a[3].pos = "South player";
a[0].pos = "West player";
a[1].pos = "North player";
a[2].pos = "East player";
return 3;
}
else if (pos == "N")
{
a[0].pos = "East player";
a[1].pos = "South player";
a[2].pos = "West player";
a[3].pos = "North player";
return 1;
}
else
{
a[2].pos = "South player";
a[3].pos = "West player";
a[0].pos = "North player";
a[1].pos = "East player";
return 2;
}
}
int main()
{
string start_pos;
cin >> start_pos;
while (start_pos != "#")
{
person a[4];
int thep=position(a, start_pos);
string card;
string card2;
cin >> card;
cin >> card2;
card += card2;
for (int i = 0; i < 104; i = i + 2)
{
int flag = i / 2;
if (flag % 4 == 0)
{
a[0].num += card[i + 1];
a[0].col += card[i];
}
else if (flag % 4 == 1)
{
a[1].num += card[i + 1];
a[1].col += card[i];
}
else if (flag % 4 == 2)
{
a[2].num += card[i + 1];
a[2].col += card[i];
}
else if (flag % 4 == 3)
{
a[3].num += card[i + 1];
a[3].col += card[i];
}
}
for (int i = 0; i < 4; i++)
{
int flag = (i + thep) % 4;
a[flag].give_value();
a[flag].sort_person();
a[flag].print();
}
cout<<endl;
cin >> start_pos;
}
return 0;
}