백준 1449 - 수리공 항승 (Python3)
코드
n, l = map(int, input().split())
arr = list(map(int , input().split()))
arr.sort()
def solution(n, l, arr):
# 붙일 테이프 개수 (최종 정답 변수)
cnt = 1
# 두 파이프 사이 간격
dist = 0
# 반복
for i in range(1, n):
# 사이 간격의 누적합을 구함
dist += arr[i]-arr[i-1]
# 같다(==) 조건이 없는 이유
# 파이프 양쪽에 0.5의 간격이 필요하다고 했음
# => l이 dist보다 커야만 확실하게 막을 수 있는 경우가 됨
# 두 파이프 사이의 간격보다 테이프의 길이가 긴 경우만 해당 됨 (같으면 안 됨)
# 테이프의 길이가 사이 간격의 누적합보다 크다?
# 이전까지 테이프 개수로 만든 길이만으로 충분히 커버 가능
# 반복 넘김
if l > dist:
continue
# 누적합보다 같거나 작다?
# 테이프를 하나 추가하고
# 누적합을 0으로 초기화함 (거기서부터 또 최소 테이프 길이부터 연산 시작)
else:
cnt += 1
dist = 0
return cnt
print(solution(n, l, arr))
문제 해설
그리디 알고리즘 문제.
문제 자체가 요구하는 바를 명확하게 이해하는 것이 매우 어려운 문제였다.
테이프로 누수를 막으면 되는 조건인데, 한 곳의 누수를 막을 때 좌우로 0.5의 간격이 필요하다는 조건이 있다. 처음 이 조건이 의미하는 바를 도무지 파악하지 못해 애를 먹었다. 조건의 의미는 아래와 같다.
만약 누수된 두 파이프의 사이 간격이 3이라면, 필요한 테이프 길이는 3 + 0.5 + 0.5이다.
이를 간단하게 생각해보면, 테이프 길이가 누수 간격과 같은 경우도 누수 간격보다 작은 경우로 생각해도 된다는 의미이다. 따라서 이를 조건으로 적어보면
# 같다(==) 조건이 없는 이유
# 파이프 양쪽에 0.5의 간격이 필요하다고 했음
# => l이 dist보다 커야만 확실하게 막을 수 있는 경우가 됨
# 두 파이프 사이의 간격보다 테이프의 길이가 긴 경우만 해당 됨 (같으면 안 됨)
# 테이프의 길이가 사이 간격의 누적합보다 크다?
# 이전까지 테이프 개수로 만든 길이만으로 충분히 커버 가능
# 반복 넘김
if l > dist:
continue
# 누적합보다 같거나 작다?
# 테이프를 하나 추가하고
# 누적합을 0으로 초기화함 (거기서부터 또 최소 테이프 길이부터 연산 시작)
else:
cnt += 1
dist = 0
위처럼 코드로 나타낼 수 있다.
댓글남기기