【蓝桥杯】最小刷题数 题解

来来来,咱先明确一个概念,“不超过”就是<=  ,翻译一下题目 ,假设我们的研究对象,就是研究的这个同学,他叫小明,本题的意思就是,要求小明刷题,最后:

比小明刷题多的人<=比小明刷题少的人

也就是比小明刷题少的人>=比小明刷题多的人,这样更方便,因为我们写数据的时候习惯从前写。

之后咱就用前缀和这个算法,记录每个分段的人数,及更新数组,使他记录这个分段及这个分段之前有多少人刷题,之后应该会有一个常数,就是这个分段的同学刷题数量刚好使两边同学相等,

找到这个分段,再处理一些细节,题目就完成了。

N = 100000
cnt = [0] * (N + 1)       # cnt[i] = number of elements <= i
#用到了前缀和
less = lambda i: cnt[i - 1] if i else 0
#意思是i如果为零,返回0,剩下返回cnt[i-1]
#cnt[i-1]的意思是刷题比这个同学少的同学数量
more = lambda i: cnt[N] - cnt[i]
#刷题比这个同学多的同学数量


if __name__ == '__main__':
    n = int(input())
    a = [int(x) for x in input().split()]

    for x in a:
        cnt[x] += 1#记录了每个刷题分段有多少同学

    for i in range(1, N + 1):#更新数组,使得数组记录每个刷题分段有多少同学刷题不超过这个分段的刷题数
        cnt[i] += cnt[i - 1]

    for i in range(N + 1):#这个东西是个常数,本题的点睛之处,就是最小刷题数
        #我们对分数遍历
        if less(i)-1 >= more(i):#这句话的意思也是刷题比这个同学少的同学数量大于等于刷题比这个同学多的同学数量
            #这地方最难理解
            #为什么要减一
            #因为如果不减一那么仅仅是刷到这个地方,如果less(i)<=more(i)的话还是不够的
            #所以我们要更上一层楼,进行必杀
            min_law = i
            break

    for x in a:
        print(0 if less(x) >= more(x) else min_law-x, end = " ")

其实找那个min_law可以用二分优化,但是我不想写了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值