【问题描述】
小蓝老师教的编程课有 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.
import java.io.*;
public class Main {
static int N=100010;
static int[] a=new int[N];
static int[] cnt=new int[N];
static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n=Integer.parseInt(br.readLine());
String[] split = br.readLine().split(" ");
for (int i=1;i<=n;i++){
a[i]=Integer.parseInt(split[i-1]);
cnt[a[i]]++;//刷了这些题数量的人数
}
//前缀和求出当前这道题刷题量的总人数
for (int i=1;i<=100000;i++){
cnt[i]+=cnt[i-1];
}
for (int i=1;i<=n;i++){
if (cnt[100000]-cnt[a[i]]<=cnt[Math.max(0,a[i]-1)]){
out.print(0+" ");
continue;
}
//去二分找到我们应该刷多少题才符合条件
//l是答案的下界、r是答案的上界
int l=a[i]+1,r=100000;
while (l<r){
int mid=(l+r)>>1;
if (cnt[100000]-cnt[mid]<=cnt[mid-1]-1) r=mid;
else l=mid+1;
}
//目标的刷题数减去当前的刷题数
out.print(r-a[i]+" ");
}
out.flush();
}
}