[코테] 백준 그리디 2141번 문제
2141번 : 우체국
문제 링크
https://www.acmicpc.net/problem/2141
문제 설명
수직선과 같은 일직선상에 N개의 마을이 위치해 있다. i번째 마을은 X[i]에 위치해 있으며, A[i]명의 사람이 살고 있다.
이 마을들을 위해서 우체국을 하나 세우려고 하는데, 그 위치를 어느 곳으로 할지를 현재 고민 중이다. 고민 끝에 나라에서는 각 사람들까지의 거리의 합이 최소가 되는 위치에 우체국을 세우기로 결정하였다. 우체국을 세울 위치를 구하는 프로그램을 작성하시오.
각 마을까지의 거리의 합이 아니라, 각 사람까지의 거리의 합임에 유의한다
입력
첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 X[1], A[1], X[2], A[2], …, X[N], A[N]이 주어진다. 범위는 |X[i]| ≤ 1,000,000,000, 1 ≤ A[i] ≤ 1,000,000,000 이며 모든 입력은 정수이다.
출력
첫째 줄에 우체국의 위치를 출력한다. 가능한 경우가 여러 가지인 경우에는 더 작은 위치를 출력하도록 한다.
문제 풀이
처음에는 특정한 우체국의 위치를 정하고, 앞뒤의 우체국보다 총 거리가 적게 나오면 출력하는 코드로 작성하였으나 시간 초과로 실패
결국 다른 사람의 코드를 찾아보니 마을들을 정렬하고, 앞에서부터 사람수를 세어 총 사람 수의 절반이 넘어가는 시점의 마을에 우체국을 정하는 게 정답이였다. 머리로는 총 사람 수의 절반이 되는 시점이 총 거리가 적게 나오는 방법이라는 생각이 들긴하지만 어떻게 이런 생각을 할 수 있을지 의문인 문제였다.
# 최초 풀이 : 시간 초과로 실패
N = int(input())
arr = []
boundary = [-2, -1, 1, 2]
total_dist = 0
total_person = 0
for _ in range(N) :
town, person = map(int, input().split())
total_dist += abs(town) * person
total_person += person
arr.append([town, person])
idx = total_dist // total_person
total_dist = 0
for i in range(N) :
town, person = arr[i]
total_dist += abs(idx - town) * person
while True :
for i in range(len(boundary)) :
count = 0
for j in range(N) :
town, person = arr[j]
count += abs(idx + boundary[i] - town) * person
if count == total_dist and boundary[i] < 0 :
idx += boundary[i]
total_dist = count
break
elif count < total_dist :
idx += boundary[i]
total_dist = count
break
else :
print(idx)
break
# 정답 코드
N = int(input())
arr = []
people = 0
for _ in range(N) :
arr.append(list(map(int, input().split())))
people += arr[-1][1]
arr.sort(key = lambda x : x[0])
count = 0
for i in range(N) :
count += arr[i][1]
if count >= people / 2 :
print(arr[i][0])
break
Comments