백준 안테나(18310)
1. 힌트
1) 단순하게 구현하면 모든 집에 대해서 나머지 집 까지의 거리의 합을 계산하게 할 수 있습니다. 이렇게 하면 이 됩니다.
2) 어떤 집에 안테나를 설치하기로 했는데 그 집에서 왼편에 있는 집의 수가 오른편에 있는 집의 수보다 많다면 여기에 설치하지 않고 왼쪽으로 옮기는 것이 무조건 이득입니다.
3) 주어진 수열을 정렬해 왼쪽에 있는 집의 개수와 오른쪽에 있는 집의 개수가 동일한 지점을 찾습니다. 당연히 번째 위치가 되는데 이 짝수일 경우 답이 두개가 되므로 이 정답입니다.
2. 접근
1) 그림으로 그려볼 수 있을까?
맨 왼쪽에 있는 집과 맨 오른쪽에 있는 집으로 직접 해보겠습니다. 만약 의 위치에 있는 집을 선택한다면 두 집 사이의 거리는 입니다.
의 위치에 있는 집을 선택한다면 입니다
의 위치에 있는 집을 선택한다면 입니다
의 위치에 있는 집을 선택한다면 입니다
이처럼 어느 집을 선택하더라도 맨 왼쪽에 있는 집과 맨 오른쪽에 있는 집과의 거리는 일정합니다. 이 말은 이보다 더 낮아질 수는 없다는 것을 뜻합니다. 더 커질 수는 있습니다 와 의 입장에서 바깥에 있는 을 선택한다면 와 사이의 거리는 인데 더 늘어나게 됩니다.
따라서 맨 가운데에 있는 집을 고르는 것이 가장 최적해입니다. 이를 위해서 정렬해줍니다.
2) 수식으로 표현할 수 있을까?
다른 방법으로 문제를 풀 수도 있습니다. 는 위치에 있는 집의 개수를 저장합니다. 는 위치에 있는 집의 좌표값의 합을 저장합니다.
어떤 집에 안테나를 선택했을 때, 모든 집까지의 거리는
왼편 : 로 구할 수 있고
오른편 : 으로 구할 수 있습니다.
와 는 누적 합 배열을 이용해 간단히 구현할 수 있습니다.
3. 구현
누적 합 배열을 이용하는 풀이입니다.
public class Main {
static long sum(long[] S, int i, int j) {
if (i > j) return 0;
return S[j] - (i == 0 ? 0 : S[i - 1]);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] S = new int[N];
// P[x] = x위치 이하 좌표값의 합 C[x] = x위치 이하 좌표의 개수 합
long[] P = new long[100001]; long[] C = new long[100001];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int i = 0; i < N; i++) S[i] = Integer.parseInt(st.nextToken());
for (int x : S) { P[x] += x; C[x]++; }
for (int i = 1; i <= 100000; i++) {
P[i] += P[i - 1]; C[i] += C[i - 1];
}
long min = Long.MAX_VALUE;
int ret = 100000;
for (int x : S) {
long sum = sum(C, 0, x - 1) * x - sum(P, 0, x - 1) +
sum(P, x + 1, 100000) - sum(C, x + 1, 100000) * x;
if (min >= sum) {
if (min > sum || (min == sum && ret > x)) ret = x;
min = sum;
}
}
System.out.println(ret);
}
}
1) 시간 복잡도
정렬해서 가운데 값을 찾는 풀이의 시간 복잡도는 당연히 정렬이 지배하므로 입니다. 이 풀이는 정렬하지 않아도 되므로 입니다.
2) 테스트 케이스
Author And Source
이 문제에 관하여(백준 안테나(18310)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@axiom0510/b18310저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)