2020春招机考汇总2:扑克牌打出最小次数、钢琴高昂旋律(拼接递增序列)

题目一:扑克牌打出最小次数

有一组扑克牌,面值为:1~10.
纸牌打出规则如下:
顺子:5张连续牌(如12345)
连对:3连对(如112233)
对子:如22
单牌:如1

输入面值的个数如:2 2 2 2 2 3 3 3 3 3
输出:打完手上所有牌最小次数

Python代码示例如下:

import sys


def card_num(nums, k):
    if len(nums)<10 or k>9: return 0                 # 纸牌种类少于10,判断的牌面大于10终止
    if nums[k] == 0: return card_num(nums, k+1)      # 该牌面没有牌了,从下一牌面开始判断

    min_num = float('inf')
    if k<=len(nums)-3 and nums[k]>=2 and nums[k+1]>=2 and nums[k+2]>=2:   # 优先处理3连对
        nums[k] -= 2
        nums[k+1] -= 2
        nums[k+2] -= 2
        min_num = min(card_num(nums, k)+1, min_num)
        nums[k] += 2
        nums[k+1] += 2
        nums[k+2] += 2
    # 处理顺子
    if k<=len(nums)-5 and nums[k] >=1 and nums[k+1] >= 1 and nums[k+2] >= 1 and nums[k+3] >= 1 and nums[k+4] >= 1:
        nums[k] -= 1
        nums[k + 1] -= 1
        nums[k + 2] -= 1
        nums[k + 3] -= 1
        nums[k + 4] -= 1
        min_num = min(card_num(nums, k)+1, min_num)
        nums[k] += 1
        nums[k + 1] += 1
        nums[k + 2] += 1
        nums[k + 3] += 1
        nums[k + 4] += 1
    # 处理对子
    if nums[k] >= 2:
        nums[k] -= 2
        min_num = min(card_num(nums, k) + 1, min_num)
        nums[k] += 2
    # 处理单牌
    if nums[k] >= 1:
        nums[k] -= 1
        min_num = min(card_num(nums, k) + 1, min_num)
        nums[k] += 1

    return min_num


if __name__ == '__main__':
    nums = sys.stdin.readline().split()     # 获取输入纸牌数目
    nums = [int(item) for item in nums]     # 转化为整型
    min_num = card_num(nums, 0)             # 调用函数计算次数
    print(min_num)

题目二:拼接递增序列

题目描述:一段钢琴旋律中每个字符都可以用一个小写英文字母表示。当这段英文字母为非递减的,称这段旋律为高昂的,如aaa,bbb,cde。用n段高昂旋律拼接出一段尽可能长的高昂旋律,问最长多长。

输入示例:
3
aaa
bbb
acd
输出:
6

Python 代码示例:

import sys


def max_string(str_list, num):                    # 寻找最大值函数
    if num == 1: return len(str_list[0])          # 子序列只有一个,直接返回
    num_list = [0 for item in str_list]           # 分别存储以排序后各个子序列开始的新序列最大长度
    max_length = 0                                # 记录最大长度
    for i in range(num):                          # 遍历子序列
        submax = 0
        for j in range(0, i):       # 有点像动态规划思想,解决子序列和之前序列构成新序列最大值
            if str_list[j][-1] <= str_list[i][0] and num_list[j]>=submax: submax = num_list[j]

        num_list[i] = submax + len(str_list[i])  # 更新以i为新序列尾的最大长度
        if num_list[i] > max_length: max_length = num_list[i]  # 更新最大值
    return max_length




if __name__ == '__main__':
    num = int(sys.stdin.readline())                    # 子序列个数
    str_list = []
    for _ in range(num):
        str_list.append(sys.stdin.readline().strip())  # 存储子序列
    str_list = sorted(str_list)                        # 为子序列排序,降低难度
    max_length = max_string(str_list, num)             # 调用寻找最大值函数
    print(max_length)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值