练习题

 

题目描述:

学校本学期共开设了 60 门课,并且每位同学会选修 5 门不同的课,小刘想知道是否存在一个 3 门课的集合,使得小刘所在班级有至少 p% ( p 为不超过 100 的非负整数) 的同学选修了这三门课。

输入数据

第一行有一个整数 t (1 ≤ t ≤ 20) ,表示有 t 组数据。

对于每组数据:

第一行有两个整数 n, p (2 ≤ n ≤ 100000,50 ≤ p ≤ 100) , n 表示小明班级的人数;

接下来的 n 行,每行有 5 个整数 ai (0 ≤ ai ≤ 59) 表示该同学选修的课程号。

输出数据

对于每组数据,如果存在至少 p% 的同学选修相同的 3 门课程,输出一行“ yes ”,否则输出“ no ”。

样例输入

1
5 80
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

样例输出

 

yes

  1. 讲讲算法思路
  2. 讲讲满足输入输出要求的代码编写
  3. Python源码

 

 

1.一开始,是这样想的:有60个数,求出60个数里的3个组合。做成含有元素34000多个的列表,用这个列表做大循环,里面再把每一个人的元素与大循环的元素比较,判断如果在里面就加入预先设定号的新列表中,最后判断这个大循环元素里的新列表的长度,是否满足标准。这样把所有情况做完。实践证明这种做法在输入数据很大时,非常耗时。故弃置。

   然后,是不是可以放弃求这个组合数,34000个循环实在太多了:把所有的输入,变成input1=[[1,2,3],[1,3,4],[4,5,6].......]与input11=[1,2,3,4,5,6,7,2,3,45.......]这两种形式。先判断input11里面出现频率最高的三个数。如果出现频率排第三的那个元素低于要求(总共5个,如果第三个低于要求,那不可能有三个相同元素了),那直接回答‘no’。如果三个频率都满足,那么1.1先把含有第一个频率数的新列表列出,这个列表也是input1的形式,把这个input1形式的input11形式求出判断出现频次第三的次数,如果满足标准,输出‘yes’,在回到1.1,把第二个频率的新列表列出。这样把三个高频率出现的主干列表都弄一次,就可以做出最后的判断了。

2.首先输入组数。用组数做输入的循环,在循环里输入要求的数据,保存到列表里面。与这个循环同一等级开始写后面的部分。也可以缩进开始写,不过这个时候就要另外保存输出了。

3.源码:

##第3代程序
from collections import Counter

def plzg(x):
    #功能:找出在列表中频率出现次数最高或比较高的数
    #x是输入列表,
    b=(Counter(x).most_common(3))#次数排在前3的数c d e
    c=list(b[0])[0]
    d=list(b[1])[0]
    e=list(b[2])[0]
    f=list(b[0])[1]#次数排第3的数,出现了多少次,用来判断终止
    g=list(b[1])[1]
    h=list(b[2])[1]
    return c,d,e,f,g,h
yyyy=[]#用以存储答案
shuruzushu=int(input())
for n1 in range(shuruzushu):
    sr1=input()#怎么获取带有空格的字符数据
    sr=sr1.split()
    stu_nums=int(sr[0])#以空格为界分开数据
    rate=int(sr[1])
    xuanke=[]#类似 [(1,2,3,4,5),(33 ,44 ,55,60,23,44)]
    xuanke2=[]#类似[1,2,3,4,5,7,5,4,9...]

    xuake01=[]
    xuanke21=[]

    xuanke22=[]

    xuanke23=[]
    
    for i in range(stu_nums):
        ai0=input()
        ai1=ai0.split()
        dw1=int(ai1[0])
        dw2=int(ai1[1])
        dw3=int(ai1[2])
        dw4=int(ai1[3])
        dw5=int(ai1[4])
        xuanke2.append(dw1)
        xuanke2.append(dw2)
        xuanke2.append(dw3)
        xuanke2.append(dw4)
        xuanke2.append(dw5)
        xuanke.append([dw1,dw2,dw3,dw4,dw5])
##################
    #新思路:把频率第一,第二,第三的序列分别找出
    out1=plzg(xuanke2)
    fh1=out1[0]#频率最高
    fh2=out1[1]#频率老二
    fh3=out1[2]#频率老三
    fh5n=out1[5]
    if fh5n/stu_nums<rate/100:
        yyyy.append('no')
        continue
    #把这三个序列分别找出
    #1.频率最高的那个
    for ii in xuanke:
        if fh1 in ii:
            dw1=int(ii[0])
            dw2=int(ii[1])
            dw3=int(ii[2])
            dw4=int(ii[3])
            dw5=int(ii[4])
            xuanke21.append(dw1)
            xuanke21.append(dw2)
            xuanke21.append(dw3)
            xuanke21.append(dw4)
            xuanke21.append(dw5)
    out1=plzg(xuanke21)
    fh5n=out1[5]
    if fh5n/stu_nums>rate/100:
        yyyy.append('yes')
        continue
    #####
    for iii in xuanke:
        if fh2 in iii:
            dw1=int(iii[0])
            dw2=int(iii[1])
            dw3=int(iii[2])
            dw4=int(iii[3])
            dw5=int(iii[4])
            xuanke22.append(dw1)
            xuanke22.append(dw2)
            xuanke22.append(dw3)
            xuanke22.append(dw4)
            xuanke22.append(dw5)
    out1=plzg(xuanke22)
    fh5n=out1[5]
    if fh5n/stu_nums>rate/100:
        yyyy.append('yes')
        continue
    ####
    for iiii in xuanke:
        if fh3 in iiii:
            dw1=int(iiii[0])
            dw2=int(iiii[1])
            dw3=int(iiii[2])
            dw4=int(iiii[3])
            dw5=int(iiii[4])
            xuanke23.append(dw1)
            xuanke23.append(dw2)
            xuanke23.append(dw3)
            xuanke23.append(dw4)
            xuanke23.append(dw5)
    out1=plzg(xuanke23)
    fh5n=out1[5]
    if fh5n/stu_nums>rate/100:
        yyyy.append('yes')
    else:
        yyyy.append('no')
for i in yyyy:
    print(i)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值