题意:
牌局由四个人构成,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成。开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。
思路:
本题的主要思路依然是 处理读入->排序->格式输出。
设计了结构体card,包含数据成员面值val和花色suit;重载了多关键字比较运算符<,用于排序,整理手牌。
设计了结构体Player,包含数据成员card数组手牌hand,当前手牌数size(读入时计数),玩家标号id;设计了成员方法get()获取一张牌,Sort()调用stl排序算法理牌,show()输出手牌。
程序的主体是以文件结束符为终止条件的循环,每个循环是一次发牌。读入的第一个字符与玩家的编号对应以决定庄家,随后读入两个表示发牌的字符串。通过循环,依此从字符串中取表示花色和大小的两个字符,通过对「庄家编号与循环次数的和」取模决定由哪个玩家(player)来获得(get)此牌。此处在处理发牌记录时偷了个懒,直接复制一次处理第一个字符串的代码再使取模偏移2,就可用在处理第二个字符串上。get(char s,char c)函数传入两个参数,对应花色和大小,分别映射为大小关系符合题意的整型,为玩家更新手牌信息。全部牌发完后,为每个玩家分别执行理牌,排序在最后一次性完成。
最后根据题目的特殊要求输出。具体实现过程见下文代码。
总结:
本题考查了字符串的读取和处理,练习了对stl库的运用。在代码的调试过程中吸取的教训是关注stl排序算法的始末和区间的开闭,以及在每次循环后要注意重置重复利用的变量。
代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct card{
int val;
int suit;
bool operator<(card& c){
//多关键字排序
if(suit!=c.suit)return suit<c.suit;
return val<c.val;
}
};
struct Player{
card hand[15];
int size;
int id;
Player(){
for(int i=1;i<=13;i++){
hand[i].val=0;
hand[i].suit=0;
}
size=0;
}
void setId(int I){
id=I;}//便于标记玩家
void clear(){
//每个循环重置
for(int i=1;i<=13;i++){
hand[i].val=0;
hand[i].suit=0;
}
size=0;
}
void get(char s,char c)