[백준] 1461 : 도서관 - Python

Chooooo·2023년 2월 3일
0

알고리즘/백준

목록 보기
35/182

도서관

문제

세준이는 도서관에서 일한다. 도서관의 개방시간이 끝나서 세준이는 사람들이 마구 놓은 책을 다시 가져다 놓아야 한다. 세준이는 현재 0에 있고, 사람들이 마구 놓은 책도 전부 0에 있다. 각 책들의 원래 위치가 주어질 때, 책을 모두 제자리에 놔둘 때 드는 최소 걸음 수를 계산하는 프로그램을 작성하시오. 세준이는 한 걸음에 좌표 1칸씩 가며, 책의 원래 위치는 정수 좌표이다. 책을 모두 제자리에 놔둔 후에는 다시 0으로 돌아올 필요는 없다. 그리고 세준이는 한 번에 최대 M권의 책을 들 수 있다.

입력

첫째 줄에 책의 개수 N과, 세준이가 한 번에 들 수 있는 책의 개수 M이 주어진다. 둘째 줄에는 책의 위치가 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 책의 위치는 0이 아니며, 절댓값은 10,000보다 작거나 같은 정수이다.

import sys
from collections import deque
sys.stdin = open("input.text", "rt")

#책을 모두 제자리에 놔둘 때 최소 걸음
N, M = map(int, input().split())
data = list(map(int, input().split()))

left = []
right = []
max_data = 0
for x in data:
    if x < 0:
        left.append(x)
    else:
        right.append(x)

    if abs(x) > abs(max_data):
        max_data = x #마지막 책 저장 ### 값으로 저장했어야 !!
        
#양수는 내림차순, 음수는 오름차순
left.sort()
right.sort(reverse = True)

res = 0 #최소 걸음
#M권 들고 가는거면 M권 중에 가장 먼 거리까지 가는데 이전 책들 다 놓을 수 있다는거 생각했어야 했음
for i in range(0, len(left), M): #M씩 커져야지
    if left[i] != max_data:
        res += abs(left[i])

for i in range(0, len(right), M):
    if right[i] != max_data:
        res += abs(right[i])

#M권 놓고 항상 제자리로 돌아와야 하므로 와복.
res = res * 2
res +=  abs(max_data) #가장 먼 곳은 놓고 끝이니까
print(res)

⚽코멘트

이 문제의 핵심은 음수 양수를 나눠서 생각할 수 있어야 했다. (책의 제자리 위치는 0이기 때문에)
그리고 가장 마지막 책을 둔 상태에서는 돌아올 필요가 없기에 절댓값이 가장 큰 거리에 있는 책이 가장 마지막으로 두어야 할 책이었다.

그렇기에 책을 갖다 두면서 그보다 가까운 책은 자연스럽게 둘 수 있는 것을 생각했다면 양수는 내림차순, 음수는 오름차순으로 정렬하면 됐다. (절댓값이 큰 값으로 먼저 가면 그 이전 값을 자연스럽게 지나가기 때문.)

  • 반복문을 통해 양수 방향에 대한 책과 음수 방향에 대한 책을 M궈씩 확인하여 최소 걸음 더하면 된다.

  • 여기서 일단 해당 abs 값만 더해준 후에 왕복이므로 *2 해주고 마지막에 가장 마지막 책의 거리만 더해주면 끝.

          
profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글