第十五届蓝桥杯省赛PythonB组H题【纯职业小组】题解(AC)

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

一个“纯职业小组”定义为由 3 名同职业的士兵组成的队伍。

判断是否有解

遍历所有职业计算出最大队伍数量。

res = 0
for i in range(n):
	res += b[i] // 3
if res < k:
	print(-1)
	continue
有解

假设有:

职业abcd
数量1234

假设 k = 1 k = 1 k=1,如果想要多选一些人,那就是不希望太快凑出队伍,可以先选 1 1 1 a a a 2 2 2 b b b 2 2 2 c c c 2 2 2 d d d(选两个是因为如果三个,就凑成一支队伍了)。

这时:

职业abcd
数量0012

已选 7 7 7 人,接下来再选一个 c c c 或者 d d d,即可凑成一支队伍。

根据上述分析,以及贪心思想,我们可以先将所有队伍取出 2 2 2 个人,若队伍为 1 1 1 人则取 1 1 1 人,此时不构成一支队伍。


好的,接下来我们要如何做?

先选出所有的 < 3 <3 <3 的人头,这些都是白送的 /doge。

  • 如果 k = 1 k = 1 k=1,那就只能再选一个人,就成一个队伍了。
  • 如果 k > 1 k > 1 k>1
    • 如果有一个剩余 ≥ 3 \geq 3 3 个人的职业,那就先选 1 1 1 个构成一支队伍,然后可以白嫖两个 /doge,因为再选两个,是不会构成一支队伍的,但是可以导致我们的答案更优。
    • 如果有一个剩余 ≥ 2 \geq 2 2 个人的职业,那就先选 1 1 1 个构成一支队伍,然后可以白嫖一个,因为再选一个,是不会构成一支队伍的,但是可以导致我们的答案更优。
    • 如果有一个剩余 ≥ 1 \geq 1 1 个人的职业,那就选 1 1 1 个构成一支队伍。

很显然,根据贪心的策略,有 3 3 3 3 3 3,无 3 3 3 2 2 2,无 2 2 2 1 1 1

那么如何处理 k = 1 k = 1 k=1 的情况,我们可以直接将读入的 k k k 直接 k − = 1 k -= 1 k=1 r e s + = 1 res += 1 res+=1,因为,如果有解的情况下,我们刚开始白嫖的时候,一定会白嫖到最少一种职业有 2 2 2 个人,那么再选一个就会导致直接构成一支队伍,但是 r e s res res 只有 + 1 +1 +1,和前面的贪心分析不合,故可以特殊处理。

import sys
sys.setrecursionlimit(1000000)
input = lambda:sys.stdin.readline().strip()

T = int(input())
for _ in range(T):
    n, k = map(int, input().split())
    h = {}
    for i in range(n):
        a, b = map(int, input().split())
        if a not in h:
            h[a] = 0
        h[a] += b
    
    b = []
    for x in h:
        b.append(h[x])
    
    n = len(b)
    
    cnt = 0
    res = 0
    for i in range(n):
        cnt += b[i] // 3
        u = min(b[i], 2)
        b[i] -= u
        res += u
    
    if cnt < k:
        print(-1)
        continue
    
    c1, c2, c3 = 0, 0, 0
    for x in b:
        c3 += x // 3
        x %= 3
        if x == 1:
            c1 += 1
        elif x == 2:
            c2 += 1
    
    k -= 1
    res += 1
    
    v = min(k, c3)
    k -= v
    c3 -= v
    res += v * 3
    
    v = min(k, c2)
    k -= v
    c2 -= v
    res += v * 2
    
    v = min(k, c1)
    k -= v
    c1 -= v
    res += v * 1
    
    print(res)

【在线测评】

在这里插入图片描述

  • 35
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯是一个国内著名的计算机比赛,为了帮助参赛者更好地准备和了解比赛的型,委会会公布历年的真并提供相应的题解。 首先,我们需要了解蓝桥杯是一个综合性的计算机比赛,测试的对象包括计算机基础知识、编程能力以及解决实际问的能力。 在历年的真中,参赛者将面临不同类型的目,包括算法设计与优化问、数据结构与算法问、编程等。其中针对Python B目主要考察的是对Python语言的掌握和应用能力。 目解答一般会包含以下几个方面的内容: 1. 目分析与理解:读取目,理解目的要求和限制条件。通过仔细分析目,确定目的输入与输出,以及问的核心。 2. 设计解决方案:根据目要求和限制条件,设计一个合适的解决方案。可以使用合适的算法和数据结构来解决问,并做出相应的性能优化。 3. 编写代码实现:根据设计的方案编写相应的代码实现。需要注意的是,Python语言有其独特的语法和特性,掌握好这些特性可以更好地完成编程任务。 4. 调试与测试:编写完代码后,需要进行调试和测试。通过运行样例输入和输出,检查代码是否符合目要求,并且没有逻辑上的错误。 5. 总结与优化:在完成目解答后,可以进行总结和优化。包括分析算法复杂度、代码风格和可读性等方面,以便在比赛中更好地表现。 在准备蓝桥杯时,可以通过阅读历年的真题解来了解比赛的难度和类型,针对性地进行练习和提高。同时也可以参加相关的培训班和讨论活动,与其他参赛者交流经验和技巧。 总而言之,历年蓝桥杯的解答对于提高自己的编程能力和应对比赛非常有帮助。通过认真分析和实践,可以更好地理解并掌握Python编程,并在比赛中取得更好的成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值