思路就是二分找第一个满足条件的值,然后达到要求即可。但是实际过程中会遇到问题:
二分找到的满足要求的值,同样将a[i]包含在内,所以在某些情况下你单纯达到是不可以的。
我们此处将第一个满足条件的值记为standardNum,小于标准值的个数littleNums,同理大于标准值的个数记为largeNums。
假如standardNum只存在一个,没有跟它相同值。那么在加值时,多加一个1,把它盖过即可。 即addNum=standardNum-a[i]+1
假如standardNum存在多个相同值。那么在加值时,需要考虑情况。对littleNums和largeNums的关系再进行判断。判断理由如下:
-
1.如果此时littleNums>largeNums,那么无需多言,a[i]成为standardNum即可。
即addNum=standardNum-a[i]; -
2.但如果此时littleNums=largeNums,那么单纯的a[i]成为standardNum是不可行的。
在没成为它之前,standardNum就只是勉强满足条件。
若你成为它,那么littleNums-1,一定是小于largeNums的。
所以此时,你还需要再+1,使得a[i]要超过standardNum。
即addNum=standardNum-a[i]+1;
Java 代码
import java.io.*;
import java.util.Arrays;
public class Main {
static int n;
static int[] a;
static int[] sortedA;
static int littleCount;
static int largeCount;
static int repeatCount;
static int satisfiedRepeatCount;
static boolean equalFlag=false;
public static boolean check(int mid) {
// 存在一个问题是,有可能需要将满足的数字放在脚底下。假如它没有相同的值,那么可以在它的基础上+1,即可。
// 假如它有相同的值的话,需要将
littleCount=0;
largeCount=0;
largeCount=0;
repeatCount=0;
int num =sortedA[mid];
for(int i=0;i<n;i++)
{
if(sortedA[i]<num) {
littleCount++;
}else if(sortedA[i]>num){
largeCount++;
}else {
repeatCount++;
}
// 如果小的已经超过一半
if(littleCount>a.length/2) {
return true;
}
}
if(largeCount<=littleCount) {
if(largeCount==littleCount) {
equalFlag=true;
}
satisfiedRepeatCount=repeatCount;
return true;
}
return false;
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(inReader.readLine());
a = new int[n];
String[] strs=inReader.readLine().split(" ");
for(int i=0;i<n;i++) {
a[i]=Integer.parseInt(strs[i]);
}
sortedA=a.clone();
Arrays.sort(sortedA);
int left=0,right=n;
while(left<right) {
int mid=left+right>>1;
if(check(mid)) {
right=mid;
}else {
left=mid+1;
}
}
int standardNum=sortedA[left];
// System.out.println("标准为:"+standardNum);
for(int i=0;i<n;i++) {
if(a[i]>=standardNum) {
System.out.print("0 ");
}else {
if(satisfiedRepeatCount==1) {
// System.out.println("repeatCount: "+repeatCount);
System.out.print(standardNum-a[i]+1+" ");
}else {
if(equalFlag) {
System.out.print(standardNum-a[i]+1+" ");
}else {
System.out.print(standardNum-a[i]+" ");
}
}
}
}
}
}