问题描述
小蓝老师教的编程课有 N 名学生, 编号依次是 1…N 。第 i 号学生这学期 刷题的数量是 Ai 。
对于每一名学生, 请你计算他至少还要再刷多少道题, 才能使得全班刷题 比他多的学生数不超过刷题比他少的学生数。
输入格式
第一行包含一个正整数 N 。
第二行包含 N 个整数: A1,A2,A3,…,AN.
输出格式
输出 N 个整数, 依次表示第 1…N 号学生分别至少还要再刷多少道题。
样例输入
5
12 10 15 20 6
样例输出
0 3 0 0 7
评测用例规模与约定
对于 30% 的数据, 1 ≤ N ≤ 1000,0 ≤ Ai ≤ 1000.
对于 100% 的数据, 1 ≤ N ≤ 100000,0 ≤ Ai ≤ 100000.
思路:
例:12 10 15 14 6
A | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
B | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
C | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 5 |
B:代表样例中所有的刷题个数
刷题数目比自己小的人数不少于成绩比刷题数目自己大的人数的最小刷题数。 用数组记录每个成绩出现的次数 ,然后维护成绩的前缀和,并遍历遍历数组,如果当前刷题数目比自己小的人数不少于刷题数目比自己大的人数 ,我们把此类学生定义为合法学生,即不用进行任何操作就可以满足要求。
反之,我们要分析不合法学生变成合法学生的最小刷题数,首先我们要找到一个当前刷题数目比自己小的人数多于刷题数目比自己大的合法学生的最小刷题数目,定义为通过刷题可以成为合法学生的所需的最小成绩。
参考代码:
num = int(input())
lis = list(map(int,input().split()))
maxn = max(lis)
N=100001
cnt = [0 for i in range(N)]
for i in range(num):
cnt[lis[i]]+=1
for i in range(1,N):
cnt[i] += cnt[i-1]
pos = -1
pos1 = -1
for i in range(1,N):
if cnt[i-1] >= num - cnt[i]: #不用刷题
if pos1 == -1 :
pos1 = i
if cnt[i-1] - 1 >= num - cnt[i]: #需要刷题
if pos == -1:
pos = i
break
if pos == -1:
for i in range(num):
print(0,end = ' ')
else:
for i in range(num):
if lis[i] >= pos1:
print(0,end = ' ')
else:
print(pos-lis[i],end = ' ')