【华为OD】2024D卷——求最多可以派出多少支团队

题目描述:
用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或2人组成,且1个人只能参加1个团队,请计算出最多可以派出多少支符合要求的团队?
输入描述:
5
3 1 5 7 9
8
第一行数组代表总人数,范围[1,500000]
第二行数组代表每个人的能力,每个元素的取值范围[1,500000],数组的大小范围[1.500000]
第三行数值为团队要求的最低能力值,范围[1,500000]
输出描述:
3
最多可以派出的团队数量
补充说明:
3.5组成一队,1.7组成一队,9自己一个队,故输出3

解题思路:

1、处理输入

2、能力值排序

3、单人组队:能力值 > 团队要求的最低能力值min_group_potential

      双人组队:双指针法,除去单人组队后,在剩余人数中确认当前最弱者与最强者的能力和能否组成一个符合要求的团队,可以双指针移动 ;不可以则移动最弱者指针

4、成功组成一个团队就增加计数器


代码部分

def max_group_number(every_potential,min_group_potential):
    every_potential.sort(reverse=True)      #能力降序排列
    count = 0
    # 单人组队
    for potential in every_potential:
        if potential >= min_group_potential:
            count  += 1
            every_potential.remove(potential)
    #双人组队
    start = 0
    end = len(every_potential) - 1
    while start < end:     #从剩余列表两端,向中间查找
        sum_potential = every_potential[start] + every_potential[end]
        if sum_potential >= min_group_potential:        #可以组队,两边向中间移动
            count += 1
            start += 1
            end -= 1
        else:       #无法组队,则移动能力最弱者指针
            end -= 1
    return count

try:
    total = int(input())
    every_potential = list(map(int, input().split()))
    min_group_potential = int(input())
    if total != len(every_potential):
        raise ValueError("输入人数与能力数量不符")
    else:
        group_number = max_group_number(every_potential, min_group_potential)
        print(group_number)
except ValueError as e:
    print(e)

优化建议:

1、避免在列表中删除元素: 在 Python 中,从列表中删除元素会导致列表重新分配和复制,这在时间复杂度上可能会增加开销。可以通过使用索引变量来代替删除操作。

2、减少不必要的排序: 列表进行了一次降序排序,但实际上双人组队的过程可以在升序排序下同样完成。因此,只需要一次升序排序即可。


#优化后的函数
def max_group_number(every_potential, min_group_potential):
    every_potential.sort()  # 仅升序排列
    count = 0
    n = len(every_potential)
    # 单人组队
    i = n - 1
    while i >= 0 and every_potential[i] >= min_group_potential:
        count += 1
        i -= 1
    # 双人组队
    start = 0
    end = i
    while start < end:
        if every_potential[start] + every_potential[end] >= min_group_potential:
            count += 1
            end -= 1
            start += 1
        else:
            start += 1
    return count

涉及知识点:列表、双指针法


结语:越简单的题目解法应该越多,请路过大神留下新的思路供本小白学习一下,打开思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值