蓝桥杯比赛python程序设计——纯职业小组
问题描述
在蓝桥王国,国王统治着一支由 nn 个小队组成的强大军队。每个小队都由相同职业的士兵组成。具体地,第 ii 个小队包含了 bibi 名职业为 aiai 的士兵。
近日,国王计划在王宫广场举行一场盛大的士兵检阅仪式,以庆祝王国的繁荣昌盛。然而,在士兵们入场的过程中,一场突如其来的风暴打乱了他们的行列,使得不同小队的士兵混杂在一起,次序乱成一团,
尽管国王无法知道每个士兵的具体职业,但为了确保仪式能顺利进行,国王打算从这些混乱的士兵中选出一部分,组成 kk 个“纯职业小组”进行检阅。一个“纯职业小组”定义为由 33 名同职业的士兵组成的队伍。
请问,国王至少需要选择多少名士兵,才能确保这些士兵可以组成 kk 个“纯职业小组”。
输入格式
输入包含多组数据。
第一行包含一个整数 TT,表示有 TT 组数据。
对于每组数据:
- 第一行包含两个整数 ntnt 和 kk,表示小队的数量和要组成的纯职业小组的数量。
- 接下来的 ntnt 行,每行包含两个整数 aiai 和 bibi,表示第 ii 个小队中士兵的职业和数量。
输出格式
对于每组数据,输出一个整数,表示为了组成 kk 个“纯职业小组”,国王至少需要选择的士兵数量。如果无论如何也无法组成 kk 个“纯职业小组”,则输出 −1−1。
样例输入
2
3 2
1 3
2 3
3 3
3 5
1 3
2 3
3 3
样例输出
8
-1
样例说明
在第一个样例中,要想组成 22 个“纯职业小组”,国王至少需要选择 88 名士兵。若只选择了 77 名士兵,则这 77 名士兵的职业可能为 1,1,1,2,2,3,31,1,1,2,2,3,3,无法组成 22 个“纯职业小组”。
在第二个样例中,即使选择了所有士兵,也无法组成 55 个“纯职业小组”,因此输出 −1−1。
评测用例规模与约定
对于 50%50% 的评测用例,1≤T≤101≤T≤10,1≤∑t=1Tnt≤2×1031≤t=1∑Tnt≤2×103,1≤ai,bi≤1051≤ai,bi≤105,1≤k≤1071≤k≤107。
对于所有的评测用例,1≤T≤1001≤T≤100,1≤∑t=1Tnt≤2×1051≤t=1∑Tnt≤2×105,1≤ai,bi≤1091≤ai,bi≤109,1≤k≤10131≤k≤1013。
运行限制
语言 | 最大运行时间 | 最大运行内存 |
---|---|---|
C++ | 1s | 256M |
C | 1s | 256M |
Java | 3s | 512M |
Python3 | 10s | 512M |
PyPy3 | 3s | 512M |
Go | 5s | 512M |
JavaScript | 5s | 512M |
问题解答:
import os
import sys
sum=int(input())
K=[]
for _ in range(sum):
sum2=input().split()
sum21=int(sum2[1])
sum20=int(sum2[0])
num_zhiye=0
num_min=0
num={}
for i in range(sum20):
sum3=input().split()
sum30=sum3[0]
sum31=int(sum3[1])
num[sum30]=num.get(sum30,0)+sum31
for sum30,sum31 in num.items():
if sum31>=3:
num_zhiye+=sum31//3
num_min+=1
else:
num_min+=sum31
if num_zhiye>=sum21:
num_min+=3*(sum21-1)+2
K.append(num_min)
else:
K.append(-1)
for i in K:
print(i)
代码详细分析
1. 导入模块
python
import os
import sys
这两行代码导入了os
和sys
模块,但在后续代码里并未使用这两个模块,所以可以将其移除。
2. 读取输入的测试数据组数
python
sum=int(input())
从标准输入读取一个整数,把它赋值给变量sum
,这个变量代表接下来要处理的测试数据组数。
3. 循环处理每组测试数据
python
K=[]
for _ in range(sum):
sum2=input().split()
sum21=int(sum2[1])
sum20=int(sum2[0])
- 初始化一个空列表
K
,用于存放每组测试数据的计算结果。 - 进入循环,循环次数为
sum
次,每次处理一组测试数据。 - 读取一行输入,利用
split()
方法将其分割成字符串列表sum2
。 - 把
sum2
中的第一个元素转换为整数,赋值给sum20
;把第二个元素转换为整数,赋值给sum21
。
4. 统计每种物品的数量
python
num_zhiye=0
num_min=0
num={}
for i in range(sum20):
sum3=input().split()
sum30=sum3[0]
sum31=int(sum3[1])
num[sum30]=num.get(sum30,0)+sum31
- 初始化变量
num_zhiye
和num_min
为 0,分别用于记录专业物品的数量和最少物品数量。 - 初始化一个空字典
num
,用于统计每种物品的总数量。 - 进入内层循环,循环次数为
sum20
次,每次读取一行输入,将其分割成字符串列表sum3
。 - 把
sum3
中的第一个元素作为物品名称,第二个元素转换为整数作为物品数量,更新字典num
中该物品的总数量。
5. 计算专业物品数量和最少物品数量
python
for sum30,sum31 in num.items():
if sum31>=3:
num_zhiye+=sum31//3
num_min+=1
else:
num_min+=sum31
- 遍历字典
num
的键值对,针对每个物品的数量进行判断。 - 若物品数量大于等于 3,则将该物品数量除以 3 的商累加到
num_zhiye
中,同时num_min
加 1。 - 若物品数量小于 3,则将该物品数量累加到
num_min
中。
6. 判断是否满足条件并更新最少物品数量
python
if num_zhiye>=sum21:
num_min+=3*(sum21-1)+2
K.append(num_min)
else:
K.append(-1)
- 若专业物品数量
num_zhiye
大于等于sum21
,则更新num_min
的值,将其添加到列表K
中。 - 若专业物品数量
num_zhiye
小于sum21
,则将 -1 添加到列表K
中。
7. 输出结果
python
for i in K:
print(i)
遍历列表K
,逐个输出其中的元素。