扑克牌大小
2016-05-24 22:51
239 查看
题目
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用”-“连接,每手牌的每张牌以空格分隔,”-“两边没有空格,如:4 4 4 4-joker JOKER。
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
(4)输入的两手牌不会出现相等的情况。
输入:
输入两手牌,两手牌之间用”-“连接,每手牌的每张牌以空格分隔,”-“两边没有空格,如 4 4 4 4-joker JOKER。
输出:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。
样例输入:
4 4 4 4-joker JOKER
样例输出:
joker JOKER
答案提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。
(3)输入的顺子已经经过从小到大排序,因此不用再排序了。
——————————-分割线—————————————
代码先留下,明天再来细说
——————————-分割线—————————————
代码能够通过测试,必须要保证输入的合法性。即输入的牌组必须合法,但是输入的两首牌不一定要是同样类型的牌组。
正常情况:
1、两首牌同类型。对于单个、对子、三个、四个以及顺子,如果两手牌类型相同则卡牌数应该相等,并且都可以通过判断第一个子串来比较两手牌的大小。
2、两首牌不同类型。这里就回出现两个子串的长度不等,而两首牌类型不同只能发生在其中一个是炸弹的情况。因此只需要找出哪手牌是炸弹即可。
特殊情况:
1、有大小王。当出现大小王时,可以直接判断出结果。
2、出现10。相对于其他卡牌只需要用一个字符来表示,“10”必须要用字符串来表示。因此在比较卡牌大小前将手牌中的“10”替换为字符串“1”。这么做的理由是,hash表中可以统一使用map< char, int >来简历卡牌的大小索引表。
代码
加油 !!!!
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用”-“连接,每手牌的每张牌以空格分隔,”-“两边没有空格,如:4 4 4 4-joker JOKER。
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
(4)输入的两手牌不会出现相等的情况。
输入:
输入两手牌,两手牌之间用”-“连接,每手牌的每张牌以空格分隔,”-“两边没有空格,如 4 4 4 4-joker JOKER。
输出:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。
样例输入:
4 4 4 4-joker JOKER
样例输出:
joker JOKER
答案提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。
(3)输入的顺子已经经过从小到大排序,因此不用再排序了。
——————————-分割线—————————————
代码先留下,明天再来细说
——————————-分割线—————————————
代码能够通过测试,必须要保证输入的合法性。即输入的牌组必须合法,但是输入的两首牌不一定要是同样类型的牌组。
正常情况:
1、两首牌同类型。对于单个、对子、三个、四个以及顺子,如果两手牌类型相同则卡牌数应该相等,并且都可以通过判断第一个子串来比较两手牌的大小。
2、两首牌不同类型。这里就回出现两个子串的长度不等,而两首牌类型不同只能发生在其中一个是炸弹的情况。因此只需要找出哪手牌是炸弹即可。
特殊情况:
1、有大小王。当出现大小王时,可以直接判断出结果。
2、出现10。相对于其他卡牌只需要用一个字符来表示,“10”必须要用字符串来表示。因此在比较卡牌大小前将手牌中的“10”替换为字符串“1”。这么做的理由是,hash表中可以统一使用map< char, int >来简历卡牌的大小索引表。
代码
#include <iostream> #include <string> #include <map> using namespace std; map<char, int> card; //判断手牌是否为炸弹 int isBomb(string s) { int count = 1; string::size_type spos = 0, epos; string tmp1="", tmp2; if ((epos = s.find_first_of(' ', spos)) != s.npos) { count++; tmp1 = s.substr(spos, epos - spos); spos = epos + 1; }else{ return -1; } while ((epos = s.find_first_of(' ', spos)) != s.npos) { count++; tmp2 = s.substr(spos, epos - spos); //各卡牌必须相同 if (tmp1 != tmp2) { return -1; } tmp1 = tmp2; spos = epos + 1; } //卡牌数目必须为4个,才算炸弹 if (count != 4) { return -1; } return 0; } //将字符串“10”替换为字符串“1” string changeTenToOne(string s) { string::size_type spos = 0, epos; string left=""; //没有“10”直接返回原字符串 if ((epos = s.find_first_of("10", spos)) == s.npos) { return s; } do { /* 提取“10”的前缀字符串并剪切到新的字符串left中,同时在前缀末尾加上“1”。 */ left += s.substr(spos, epos - spos) + "1"; spos = epos + 2; if (spos >= s.size()) { return left; } } while ((epos = s.find_first_of("10", spos)) != s.npos); left += s.substr(spos); return left; } //手牌中卡牌数目 int numOfCard(string s) { int count = 1; string::size_type pos = 0; while ((pos = s.find_first_of(' ', pos)) != s.npos) { count++; pos++; } return count; } void compareCard(string s) { string s1, s2; string ss1, ss2; string::size_type pos = 0; int size1, size2; //提取两副手牌 pos = s.find_first_of('-', pos); ss1 = s.substr(0, pos); ss2 = s.substr(pos + 1); //替换手牌中可能存在的“10”字符串 s1 = changeTenToOne(ss1); s2 = changeTenToOne(ss2); //统计手牌中卡牌数目 size1 = numOfCard(s1); size2 = numOfCard(s2); //处理手牌中有大小王的情况 if (s1 == "joker" || s1 == "JOKER" || s1 == "joker JOKER") { if ((s1 == "joker JOKER") || (s1 == "JOKER" && size2 == 1)) { cout << ss1 << endl; } else if (s1 == "joker" && size2 == 1) { if (s2 == "JOKER") { cout << ss2 << endl; }else{ cout << ss1 << endl; } } else { cout << "ERROR" << endl; } return; } if (s2 == "joker" || s2 == "JOKER" || s2 == "joker JOKER") { if ((s2 == "joker JOKER") || (s2 == "JOKER" && size1 == 1)) { cout << ss2 << endl; } else if (s2 == "joker" && size1 == 1) { if (s1 == "JOKER") { cout << ss1 << endl; } else { cout << ss2 << endl; } } else { cout << "ERROR" << endl; } return; } //正常情况的手牌比较 if (size1 == size2) { switch (size1) { //单个、对子、三个、炸弹 case 1: case 2: case 3: case 4: if (card[s1[0]] > card[s2[0]]) { cout << ss1 << endl; }else{ cout << ss2 << endl; } break; //顺子 default: if (card[s1[0]] > card[s2[0]]) { cout << ss1 << endl; }else{ cout << ss2 << endl; } break; } } else { if (isBomb(s1) == 0) { cout << ss1 << endl; } else if (isBomb(s2) == 0) { cout << ss2 << endl; } else { cout << "ERROR" << endl; } } } //初始化为hash索引表 void init() { char tmp; for (int i = 3; i <= 10; i++) { //卡牌10的hash索引用‘1’来替代 if (i == 10) { tmp = (1 + '0'); } else { tmp = (i + '0'); } card[tmp] = i - 3; } card['J'] = 8; card['Q'] = 9; card['K'] = 10; card['A'] = 11; card['2'] = 12; return; } int main() { string s; init(); while (getline(cin, s)) { compareCard(s); } return 0; }
加油 !!!!
相关文章推荐
- STM32F1_常见外设资源汇总
- 51nod 1624 取余最长路
- 算法导论-二进制数组相加
- java int与integer的区别
- 前端面试题
- C++上机作业6
- mysql 优化常用语句
- nth-child选择器
- C#下使用protobuf(Google Protocol Buffers)
- Android笔记:OptionsMenu
- CSS3伪类选择器
- 人一切的痛苦,本质上都是对自己的无能的愤怒。──王小波
- 第九周项目二-我的数组类
- js图片自动循环播放
- c++课后作业
- 团队第二次冲刺(1-10天)
- 自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果
- windows下tree命令列出文件目录树
- SQL Server代理警报
- 使用PowerDesigner画ER图详细教程