CSP-training Week 2 Problem 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的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。

读入样例

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|
±–±--±–±--±–±--±–±--±–±--±–±--±–+

问题重述

四个方位坐定四个参与者,每个人的位置不再变化。每次输入一个方位,这个方位作为本次发牌员,他的顺时针方向下一个参与者作为发牌的起始位置。
备注顺时针方向是:

East
South
West
North

输入的两行字符串代表52张牌,每两个字符代表一张牌
两个字符中的第一个代表花色
规定花色的排行升序如下:

C
D
S
H

第二个字符代表牌面的大小
规定牌面的大小关系升序如下:

2
3
4
5
6
7
8
9
T
J
Q
K
A

根据输入的位置和字符串,为每个人发牌,并按照上述的顺序输出相应形式的牌面

解题思路

思路概述

基本结构:
构造了一个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;
}
发布了17 篇原创文章 · 获赞 2 · 访问量 1666

猜你喜欢

转载自blog.csdn.net/qq_43942251/article/details/104645660