백준 문제풀이
2110번: 공유기 설치 / gold 4 / 이분탐색
RonLee
2023. 2. 14. 17:29
https://www.acmicpc.net/problem/2110
2110번: 공유기 설치
첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가
www.acmicpc.net
메모리 초과
'''
2110번: 공유기 설치 / gold 4
'''
import sys
import itertools
input = sys.stdin.readline
n, c = map(int, input().split())
arr = []
for _ in range(n):
arr.append(int(input()))
arr.sort()
comb = list(itertools.combinations(arr, c))
max_res = 0
for i in range(len(comb)):
min_res = int(1e9)
for j in range(1, c):
tmp_res = comb[i][j] - comb[i][j - 1]
if min_res > tmp_res:
min_res = tmp_res
if min_res > max_res:
max_res = min_res
print(max_res)
오답 코드 (구현 생각)
- n개 중 c개 선택 한 경우의 수에서 -> 공유기 사이의 최대 거리 인놈 찾기
- 시간 초과가 날 것 같은 기분?
1. arr 리스트 만들어서 입력 받은 것 오름차순 정렬하기
2. comb 조합 경우의 수 만들기
3. 경우의 수 하나하나 모두 확인하기
정답
'''
2110번: 공유기 설치 / gold 4 / 이분탐색
'''
import sys
input = sys.stdin.readline
n, c = map(int, input().split())
arr = []
for _ in range(n):
arr.append(int(input()))
arr.sort()
max_res = 0
start = 1
end = arr[-1] - arr[0]
while start <= end:
mid = (start + end) // 2
now = arr[0]
count = 1
for i in range(1, len(arr)):
if arr[i] >= now + mid:
count += 1
now = arr[i]
if count >= c:
start = mid + 1
max_res = mid
else:
end = mid - 1
print(max_res)
이분탐색 활용
- 최소거리(1) 와, 최대거리(arr[-1]-arr[0])를 start, end로 지정하여 이분 탐색 진행하기
- mid 는 각 공유기의 간격을 의미
- mid 간격에 따라서 집들의 개수가 얼마나 count 되었는지 확인 하기
(count 가 c보다 크거나 같을 때, mid 간격이 좁다는 의미)
(count 가 c보다 작을 때, mid 간격이 크다는 의미)
해당 문제가 어려운 점
1. mid 를 간격으로 해서 집들의 개수를 count 하려는 아이디어를 전혀 생각하지 못함.
두 공유기 사이의 최대 거리 == 최대 중간값 (mid의 최댓값)