题目描述:已知KTV房间内有x个麦克风(最多x个人一起唱),同一时刻只能唱一首歌。现有n个人去唱歌,共有y首歌的时间。问:当他们离开时,所有人想唱的歌是否已经唱完。
输入描述:第一行是一个整数 t,表示待测试案例数;
第二行三个整数 n,x,y (唱歌人数、同时唱歌可容纳的人数、可唱y首歌曲的时间)
接下来从上到下的每行,表示n个人想唱的歌曲,第一个元素为个人想唱歌数量,后面 表示歌曲编号。
输出描述:对于每组测试案例,所有人均唱完想唱歌曲,输出“YES”;否则输出“NO”。
情况一:
样例输入
1
3 3 3
1 2
1 3
1 4
样例输出
YES
情况二:
样例输入
2
1 1 1
2 1 2
2 2 1
1 1
1 1
样例输出
NO
YES
情况三:
样例输入
1
3 2 3
2 1 2
2 1 3
2 1 2
样例输出
NO
解决思路:1. 需要考虑所有人想唱的不同歌曲数量之和是否小于等于总共可唱歌曲时间y。例如上面第一种情况:同学1想唱歌曲2,同学2想唱歌曲3,同学3想唱歌曲4,总共有y=3首歌的时间,因此,每位同学想唱歌曲均可以唱完;如果所有同学想唱的不同歌曲数量之和(例如有:歌曲1~4)大于总共可唱歌曲的时间y(y=3), 那么总会有一首歌没有被唱到。
在1. 基础上,我们还要考虑上面第三种情况:总共有3首歌的时间(y=3), 所有同学也只想唱3首不同的歌(歌曲1~3), 但是每首歌只容纳两个人唱,对于歌曲1有3位同学想唱,这必定有一位同学无法参与到同时唱的过程中,只能等待下首歌时再唱。上述第三种情况可以这样进行:第一首歌的时间,同学1和同学2唱歌曲1;第二首歌的时间,同学1和同学3唱歌曲2;第三首歌的时间同学2唱歌曲3;最后还剩同学3想唱的歌曲1没唱到,最终输出为NO。因此我们还需要考虑同首歌想唱同学的数量与可同时容纳唱歌人数的关系。
2. 要考虑到多个测试案例 同时输入的情况,例如上面的第二种情况:第一行表示总共有 2个测试案例,接下来第二三行为案例一,第四五六行为案例二。
代码如下:
import math
# 确定输入几个案例,利用while循环将每个案例输入获取结果
case = int(input())
while case:
n, x, y = map(int, input().split())
# 统计所有人想唱的歌曲song_all
# 统计去除重复歌曲后的song_all(不同类型歌曲的数量)
song = []
song_all = []
for i in range(n):
b = list(map(int, input().split()))
for i in range(1, len(b)):
song_all.append(b[i])
if b[i] not in song:
song.append(b[i])
# 利用字典统计存储同首歌有多少同学想唱
dict = {}
for item in song:
dict.update({item: song_all.count(item)})
# 计算所有同学按照规定唱完所有想唱歌曲,需要几首歌的时间
nums = len(song)
for i in dict.keys():
# 计算所有想唱第i首歌所需要的时间(几首歌的时间)
# math.ceil()向上取整
nums1 = math.ceil(dict[i] / x) - 1
nums += nums1
# 判断是否可以唱完
if nums <= y:
print('YES')
else:
print('NO')
case -= 1