solution(通过50%)
忽略了存在分数相同的情况,若从p位置开始有若干个相同分数的无需再多刷,但是在p位置前若干个(含p位置)分数相同则都需要多刷一道题。
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn], b[maxn], f[maxn];
int main(){
int n, p;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
b[i] = a[i];
}
sort(b + 1, b + n + 1);//名次到分数
p = n / 2 + 1;//首位到达刷题数的位置
for(int i = 1; i <= n; i++){
if(i >= p) f[b[i]] = 0;//分数对应的需刷题数
else f[b[i]] = b[p] - b[i] + 1;
}
for(int i = 1; i <= n; i++){
printf("%d ", f[a[i]]);
}
return 0;
}
solution
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn], b[maxn], f[maxn];
int main(){
int n, p, l, r;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
b[i] = a[i];
}
sort(b + 1, b + n + 1);//名次到分数
p = n / 2 + 1;//中间位置
l = lower_bound(b + 1, b + n + 1, b[p]) - b - 1;//中间位置元素前的第一个位置
r = upper_bound(b + 1, b + n + 1, b[p]) - b;//中间位置元素后的第一个位置
for(int i = 1; i <= n; i++){
if(a[i] == b[p]){//对于中间位置元素值的处理
if(l >= n - r + 1) printf("0 ");//已经满足 多 <= 少 ,则无需多刷题
else printf("1 ");//不满足 多 <= 少,需要多刷一道题超过同分数的人来达成条件
}
else if(l > n - r + 1) printf("%d ", max(0, b[p] - a[i]));//当 少 > 多 时,对于题量足够的同学无需再刷(下同);对于题量不够的同学至少要刷到中间位置
else printf("%d ", max(0, b[p] - a[i] + 1));//当 少 <= 多, 对于题量不够的同学至少要超过中间位置同学的题量.注意等于的情况,再变成中间位置,只会让少 < 多
}
return 0;
}