문제
1461번: 도서관
첫째 줄에 책의 개수 N과, 세준이가 한 번에 들 수 있는 책의 개수 M이 주어진다. 둘째 줄에는 책의 위치가 주어진다. N은 10,000보다 작거나 같은 자연수이고, M은 10,000보다 작거나 같다. 책의 위치
www.acmicpc.net
- 세준이는 도서관에서 일한다.
- 도서관의 개방시간이 끝나서 세준이는 사람들이 마구 놓은 책을 다시 가져다 놓아야 한다.
- 세준이는 현재 0에 있고, 사람들이 마구 놓은 책도 전부 0에 있다.
- 각 책들의 원래 위치가 주어질 때, 책을 모두 제자리에 놔둘 때 드는 최소 걸음 수를 구하는 문제이다.
- 세준이는 한 걸음에 좌표 1칸씩 가며, 책의 원래 위치는 정수 좌표이다.
- 책을 모두 제자리에 놔둔 후에는 다시 0으로 돌아올 필요는 없다.
- 그리고 세준이는 한 번에 최대 M권의 책을 들 수 있다.
- 책의 개수 N과, 세준이가 한 번에 들 수 있는 책의 개수 M이 주어진다.
- N은 10,000보다 작거나 같은 자연수이고, M은 10,000보다 작거나 같다.
- 책의 위치가 주어진다 책의 위치는 0이 아니며, 그 절댓값이 10,000보다 작거나 같다.
알고리즘
- 책의 개수와 한 번에 들 수 있는 책의 개수를 입력받는다.
- 책의 제자리 위치를 입력받아 리스트 변수에 넣는다.
- 책의 제자리 위치는 양수 음수로 되어있으므로 양수 음수로 나누어 계산한다.
- 책을 모두 제자리에 놔둔 후에는 원래 자리인 0으로 돌아올 필요가 없기 때문에 제일 멀리 있는 책을 제일 마지막에 놔둔다.
- 책을 갔다 두면서 그보다 가까운 책을 같이 가져가 책을 놔둘 수 있으므로 양수는 내림차순, 음수는 오름차순으로 정렬한다.
- 반복문을 통해 양수 방향에 책과 음수 방향에 책을 m권씩 확인하여 최소 걸음 수에 더한다.
- 최소 걸음 수는 왕복해야 하기 때문에 곱하기 2를 하고 제일 멀리 있는 책의 위치를 더한다.
코드
import sys
n, m = map(int, sys.stdin.readline().split())
walk = list(map(int, sys.stdin.readline().split()))
plus_walk = []
minus_walk = []
max_walk = 0 # 제일 멀리 있는 책의 위치
for i in walk:
# 양수와 음수를 나눈다.
if i > 0:
plus_walk.append(i)
else:
minus_walk.append(i)
# 책을 모두 제자리에 놔둔 후에는 다시 0으로 돌아올 필요 없기때문에
# 마지막 책은 제일 멀리 있는 책으로 정한다.
if abs(i) > abs(max_walk):
max_walk = i
# 양수는 내림차순으로 음수는 오름차순으로 정렬한다.
plus_walk.sort(reverse= True)
minus_walk.sort()
# 최소 걸음 수
walking = 0
# m권을 들고 양수 방향에 책을 모두 제자리에 놔둔다.
for j in range(0, len(plus_walk), m):
# 제일 멀리 있는 책은 무시한다.
if plus_walk[j] != max_walk:
walking += plus_walk[j]
# m권을 들고 음수 방향에 책을 모두 제자리에 놔둔다.
for k in range(0, len(minus_walk), m):
# 제일 멀리 있는 책은 무시한다.
if minus_walk[k] != max_walk:
# 최소 걸음 수를 계산하기 위해 절대값으로 바꿔 더한다.
walking += abs(minus_walk[k])
# 최소 걸음 수는 책의 제자리 위치와 현재 책의 위치를 왕복하여 계산한다.
walking *= 2
# 제일 멀리 있는 책을 놔둔다.
walking += abs(max_walk)
print(walking)
결과
위 코드에서 반복문을 확인해보면 m권씩 증가시켜 각 리스트를 반복한다. m권씩 증가시켜 확인하는 이유는 양수 방향에 있는 책은 내림차순, 음수 방향에 있는 책은 오름차순으로 정렬했기 때문에 m권씩 들고 갈 때, 제일 첫 번째 책을 놔두면서 그전에 있는 책을 모두 놔둘 수 있게 되기 때문이다. 따라서 m권씩 들고 갈 때에 첫 번째 책을 최소 걸음수에 더하는 것을 확인할 수 있다. 최소 걸음수는 모두 양수로 받아 더하고 책을 놔둘 때 왕복을 하기 때문에 곱하기 2를 해주는 것을 알 수 있다. 마지막으로는 제일 멀리 있는 책을 더하여 최소 걸음수를 구할 수 있게 된다.
github
junjange/CodingTest
내가 푼 코딩 테스트 문제와 해결법. Contribute to junjange/CodingTest development by creating an account on GitHub.
github.com
'CodingTest > Baekjoon' 카테고리의 다른 글
[baekjoon] 백준 19939번(파이썬): 박 터뜨리기 (0) | 2021.06.20 |
---|---|
[baekjoon] 백준 2138번(파이썬): 스위치 (1) | 2021.06.19 |
[baekjoon] 백준 2109번(파이썬): 순회강연 (0) | 2021.06.17 |
[baekjoon] 백준 1758번(파이썬): 알바생 강호 (0) | 2021.06.16 |
[baekjoon] 백준 2457번(파이썬): 공주님의 정원 (0) | 2021.06.15 |