https://softeer.ai/practice/info.do?idx=1&eid=1204&sw_prbl_sbms_sn=107822
처음 이 문제를 보고 어느 컴퓨터를 최소로 해야하는지 판단이 안되었고 따라서 모든 경우의 수를 따져보아야 생각했고, 제약 사항을 보니
10^5(N) x 10^9(ai) = 10^14 이므로 완전탐색으로는 시간초과가 날 것이 틀림없어서 바로 이분탐색을 떠올렸습니다.
이분탐색과 파라메트릭 서치를 이용해서 문제를 해결하였습니다.
//a는 입력받은 배열(컴퓨터)
Arrays.sort(a); //오름차순 정렬
long left = a[0]; //최솟값으로 초기화
long right = a[N - 1] + (long)Math.sqrt(B);
//최댓값 + B원으로 최대 업그레이드 점수
long answer = 0;
while (left <= right) {
long mid = (left + right) / 2;
if (파라메트릭 조건 == 참) {
left = mid + 1;
answer = mid;
} else {
right = mid - 1;
}
}
public static boolean calculate(long min, int[] a, long B) {
long cost = 0;
for (int i : a) {
if (i < min) {
cost += (min - i) * (min - i);
if (cost > B) return false;
}
}
return true;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Softeer_cluster {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] str = br.readLine().split(" ");
int N = Integer.parseInt(str[0]);
long B = Long.parseLong(str[1]);
str = br.readLine().split(" ");
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = Integer.parseInt(str[i]);
}
Arrays.sort(a);
long left = a[0];
long right = a[N - 1] + (long)Math.sqrt(B);
long answer = 0;
while (left <= right) {
long mid = (left + right) / 2;
if (calculate(mid, a, B)) {
left = mid + 1;
answer = mid;
} else {
right = mid - 1;
}
}
System.out.println(answer);
}
public static boolean calculate(long min, int[] a, long B) {
long cost = 0;
for (int i : a) {
if (i < min) {
cost += (min - i) * (min - i);
if (cost > B) return false;
}
}
return true;
}
}