题解 | #扑克牌大小#
扑克牌大小
http://www.nowcoder.com/practice/d290db02bacc4c40965ac31d16b1c3eb
题目的主要信息:
总的来说就是比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。牌与牌之间比较的规则如下:
- 炸弹和对王可以和所有牌,其他类型的牌只能跟相同类型的比较。
- 个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
方法一:
首先将输入分成两副手牌,然后遍历两副手牌,用getLen函数分别计算两副手牌的长度,便于后续的比较。
- 如果任意一方有王炸,直接输出王炸即可。
- 若没有王炸,且两副手牌长度相同,如果有大王,则输出大王。否则用Value函数获得第一张牌面的值,比较两副牌第一个牌面的大小。
- 若没有王炸,且两幅手牌长度不同,如果有一方是炸弹,则输出炸弹,否则无法比较,输出ERROR。
具体做法:
#include<iostream>
#include<string>
using namespace std;
int getLen(string s)//得到出牌的张数
{
int len = 1;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ') len++;
}
return len;
}
int Value(string s)//比较第一个牌面的大小
{
int res;
if (s[0] == '1') res = 10;
else if (s[0] == '3') res = 3;
else if (s[0] == '4') res = 4;
else if (s[0] == '5') res = 5;
else if (s[0] == '6') res = 6;
else if (s[0] == '7') res = 7;
else if (s[0] == '8') res = 8;
else if (s[0] == '9') res = 9;
else if (s[0] == 'J') res = 11;
else if (s[0] == 'Q') res = 12;
else if (s[0] == 'K') res = 13;
else if (s[0] == 'A') res = 14;
else if (s[0] == '2') res = 15;
return res;
}
int main()
{
string str;
while (getline(cin, str))
{
string s1 = str.substr(0, str.find('-'));//第一手牌
string s2 = str.substr(str.find('-') + 1);//第二手牌
int n1 = getLen(s1);//第一手牌的个数
int n2 = getLen(s2);//第二手牌的个数
string Joker = "joker JOKER";//王炸!
if (s1 == Joker || s2 == Joker){//如果有一手牌是王炸则王炸最大
cout << Joker << endl;
}else if(n1 == n2){//两手牌张数相同时
if(s1 == "JOKER" || s2 == "JOKER"){//大王最大
cout<<"JOKER"<<endl;
continue;
}
int v1 = Value(s1);
int v2 = Value(s2);
if(v1 > v2){//比较第一张牌的大小,输出更大的那个
cout<<s1<<endl;
}else{
cout<<s2<<endl;
}
}else if(n1 == 4) cout<<s1<<endl;//若两手牌张数不同,炸弹最大
else if(n2 == 4) cout<<s2<<endl;
else cout<<"ERROR"<<endl;//手牌张数不同,也没有炸弹则无法比较
}
return 0;
}
复杂度分析:
- 时间复杂度:,判断语句只花费常数时间,字符串的长度为常数,getLen函数也只花费常数时间。
- 空间复杂度:,只用了常数空间。
方法二:
整体思想和方法一相同,但在这里使用类对卡牌进行分装,用defineType函数获得手牌的类型,defineWeight函数获取手牌的权重,用compareCard函数比较牌面大小。用类封装的好处是便于拓展。
具体做法:
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
enum cardType{ JOKERPAIR, BOOM, STRING, PAIR, SINGLE, JOKER };
const int count = 3;
//规定每张牌的权重
unordered_map<char, int>weightIdx = {
make_pair('3', 0),
make_pair('4', 1),
make_pair('5', 2),
make_pair('6', 3),
make_pair('7', 4),
make_pair('8', 5),
make_pair('9', 6),
make_pair('1', 7),
make_pair('J', 8),
make_pair('Q', 9),
make_pair('K', 10),
make_pair('A', 11),
make_pair('2', 12) };
//判断手牌的类型
cardType defineType(string str){
if (str == "JOKER" || str == "joker"){//大王或小王
return JOKER;
}
if (str.size() == 11 && (str[0] == 'j' || str[0] == 'J')){//对王
return JOKERPAIR;
}
if (str.size() == 7 || str.size() == 11){//炸弹,例如4 4 4 4或10 10 10 10
return BOOM;
}
if (str.size() <= 2 || str == "JOKER" || str == "joker"){//个子
return SINGLE;
}
if (str.size() == 9 || str.size() == 10){//顺子
return STRING;
}
return PAIR;//对子
}
//判断权重
int defineWeight(string str, cardType type){
int w = 0;
switch (type){
case JOKERPAIR:
w = 100;
break;
case BOOM:
case STRING:
case PAIR:
case SINGLE:
w = weightIdx[str[0]];
break;
case JOKER:
w = (str[0] == 'J' ? 1 : 0);
break;//区别大王小王
default:break;
}
return w;
}
//牌组类
class Card{
public:
string value;//牌面内容
cardType type;//牌组类型
int weight;//牌组权重
public:
explicit Card(string value) : value(value){//初始化
type = defineType(value);//获得类型
weight = defineWeight(value, type);//获得权重
}
};
//输出较大牌组
void compareCard(const Card&c1, const Card&c2){
if(c1.type == JOKERPAIR || c2.type == JOKERPAIR){//有对王存在时,对王最大
cout<<"joker JOKER"<<endl;
}
else if (c1.type == BOOM&&c2.type == BOOM){//比较两个炸弹的大小
if(c1.weight > c2.weight){
cout << c1.value << endl;
}else{
cout << c2.value << endl;
}
}else if (c1.type == BOOM || c2.type == BOOM){//有一方为炸弹时,输出炸弹
if(c1.type == BOOM){
cout << c1.value << endl;
}else{
cout << c2.value << endl;
}
}else if (c1.type != c2.type){//两副手牌类型不同时
if(c1.type == JOKER){
cout << c1.value << endl;
}else if(c2.type == JOKER){
cout << c2.value << endl;
}else{
cout << "ERROR" << endl;
}
}else{//相同类型的比较
if(c1.weight > c2.weight){
cout << c1.value << endl;
}else{
cout << c2.value << endl;
}
}
}
int main(){
string str;
while (getline(cin, str)){
int len = str.size();
int i = len;
string s1 = str.substr(0, str.find('-'));//第一手牌
string s2 = str.substr(str.find('-') + 1);//第二手牌
Card crd1(s1), crd2(s2);
compareCard(crd1, crd2);
}
return 0;
}
复杂度分析:
- 时间复杂度:,判断语句只花费常数时间。
- 空间复杂度:,只用了常数空间。