HJ88 扑克牌大小 题解

by 限时烟花

1. 抽丝剥茧

这是一道比较偏向应用的题目,是要解决一个比较实际的问题,主要是能够理解清楚题目中的规则和要求,就会比较好解决。

2. 化繁为简

首先我们还是来看一下题目中设定的规则:

  1. 两手牌只有单子、对子、五张牌的顺子、炸弹和对王这五种情况;
  2. 只有炸弹和可以和其他所有的不同的牌比较。单子、对子、顺子都只能和自己同类型的牌比较;
  3. 其余规则比较明确,不再重复

依据上述的规则,我们可以首先考虑以下几点:

  1. 对王可以视作最大的炸弹;
  2. 当没有炸弹的情况下,手牌类型和牌的数量是挂钩的,即单子对应一张,对子对应两张,顺子对应五张。而炸弹有四张和两张(对王)的可能;
  3. 为了能够方便比较,我们可以将手牌映射到一个数字序列上。

3. 码上行动

reflect = {
    '3': 3, '4': 4, '5': 5, '6':6, '7':7, '8': 8, '9': 9, '10': 10,
    'J': 11, 'Q': 12, 'K': 13, 'A': 14, '2': 15, 
    'joker': 16, 'JOKER': 17 
}


def isboom(cards):
    if len(cards) == 4 and len(set(cards)) == 1:
        return True
    elif 'joker' in cards and 'JOKER' in cards:
        return True
    else:
        return False


while True:
    try:
        s = input().split('-')
        cards1, cards2 = s[0].split(), s[1].split()
        len1 ,len2 = len(cards1), len(cards2)
        # 处理有炸弹的情况
        if isboom(cards1) and isboom(cards2):
            if reflect[cards1[0]] < reflect[cards2[0]]:
                print(s[1])
            else:
                print(s[0])
        elif isboom(cards1):
            print(s[0])
        elif isboom(cards2):
            print(s[1])
        elif len1 == len2:  # 没有炸弹存在的情况
            if reflect[cards1[0]] < reflect[cards2[0]]:
                print(s[1])
            else:
                print(s[0])
        else:
            print('ERROR')
    except:
        break

4. 例题图解

alt

5. 心有成算

时间复杂度:因为在isboom函数的判断中需要对joker和JOKER元素进行判断,故时间复杂度为O(n)O(n)

空间复杂度:使用了输入长度的变量作为临时变量存储数据等,故空间复杂度为O(n)O(n)

6. 另辟蹊径

我们也可以单独处理对王的情况,这会使得代码更加清晰:

reflect = {
    '3': 3, '4': 4, '5': 5, '6':6, '7':7, '8': 8, '9': 9, '10': 10,
    'J': 11, 'Q': 12, 'K': 13, 'A': 14, '2': 15, 
    'joker': 16, 'JOKER': 17 
}


def isdoublejoker(cards):
    if 'joker' in cards and 'JOKER' in cards:
        return True
    else:
        return False


def isboom(cards):
    if len(cards) == 4 and len(set(cards)) == 1:
        return True
    else:
        return False


while True:
    try:
        s = input().split('-')
        cards1, cards2 = s[0].split(), s[1].split()
        # print(s1, s2)
        len1 ,len2 = len(cards1), len(cards2)
        # 处理对王的情况
        if isdoublejoker(cards1):
            print(s[0])
        elif isdoublejoker(cards2):
            print(s[1])
        # 处理有炸弹的情况
        else:
            isboom1, isboom2 = isboom(cards1), isboom(cards2)
            if isboom1 and isboom2:
                if reflect[cards1[0]] < reflect[cards2[0]]:
                    print(s[1])
                else:
                    print(s[0])
            elif isboom1:
                print(s[0])
            elif isboom2:
                print(s[1])
            else:  # 没有炸弹存在的情况
                if len1 == len2:  #可以比较
                    if reflect[cards1[0]] < reflect[cards2[0]]:
                        print(s[1])
                    else:
                        print(s[0])
                else:  #不能比较
                    print('ERROR')
    except:
        break

运行情况和上述一致,时空复杂度也均为O(n)O(n)