BOJ_1461 도서관
- TOC {:toc}
이 글은 백준 온라인 저지의 1461번 문제를 풀이한 것을 모아놓은 글입니다.
일종의 연습 기록이며 제가 정답을 받은 코드와 참고할만한 다른 코드를 같이 기록합니다. 필요한 경우 코드에 대한 해설을 기록합니다만 코드는 통과했어도 해설은 틀릴 수 있기 때문에 가볍게 참고해주시길 부탁드립니다. 피드백은 편하신 방법으로 자유롭게 주시면 감사하겠습니다.
2021.07.14 (Python)
메모리 | 시간 | 코드 길이 |
---|---|---|
31260 KB | 76 ms | 409 B |
단계 | 시작 시각 | 끝난 시각 | 걸린 시간 |
---|---|---|---|
문제 이해 | 14:29:00 | 14:30:32 | |
풀이 생각 | 14:30:33 | 14:38:39 | |
코딩 | 14:41:38 | 14:59:36 | |
디버깅 1 | 15:00:37 | 15:17:32 | |
디버깅 2 | 15:41:46 | 16:06:07 |
import sys
from bisect import bisect_left
input = sys.stdin.readline
def work(book):
step = 0
for i in range(0, len(book), M):
step += abs(book[i]) * 2
return step
N, M = map(int, input().split())
books = list(map(int, input().split()))
books.sort()
idx = bisect_left(books, 0)
last = max(abs(books[0]), books[-1])
res = work(books[:idx]) + work(books[idx:][::-1]) - last
print(res)
아이디어 & 풀이
책이 0에 있기 때문에
양수 위치에서 음수 위치로 넘어갈 때는 0을 반드시 통과해야 하므로 양수 위치의 책과 음수 위치의 책을 동시에 정리하는 것은 의미가 없다.
- 입력받은 책 위치를 양수와 음수 부분을 나눠서 계산한다.
되도록 먼 곳에 있는 책을 한 번에 여러 권 갖다둬야 걸음 수를 최소화 할 수 있다. 예제 입력 1의 음수 부분을 예시로 봐보자.
- 위치: -39, -37, -29, -28, -6
- 가까이 있는 책 부터 2권씩 옮기면 걸음 수는 28 x 2 + 37 x 2 + 39로 총 169이다
- (6, 28), (29, 37), 39
- 멀리 있는 책 부터 2권씩 옮기면 걸음 수는 6 x 2 + 29 x 2 + 39로 총 109이다.
- (6), (28, 29), (37, 39)
마지막 책은 편도로만 가도 되기 때문에 가장 멀리 있는 책을 마지막으로 옮기는 것이 좋다.
- 양수 위치와 음수 위치 중 최댓값을 구해
- 전체를 왕복으로 반복했을 때 걸음 수에서 빼주면 된다.
디버그
unBoundLocalError
가 떴다.- 찾아보니까 변수 scope와 관련된 에러였다.
- https://sikaleo.tistory.com/99
- 함수 내에서 반복할 때
i
를 따로 초기화를 하지 않고range
를 이용해서 사용한 후, 그 밖에서 다시 사용하려고 해서 에러가 난 것 같다. - 원래
i
는 1단위로 순회하면서 인덱스에서M
을 곱해 더해야 하는 위치에 접근한 후, 마지막 남은 원소(e.g., 위 예시의 6 같은 경우)가 존재하면 따로 처리했는데 그냥range
의step
을M
으로 처리하는 방식으로 바꿔서 해결했다.- 덕분에 코드가 훨씬 깔끔해졌다.
- 양수 위치와 음수 위치를 각각 계산하기 위해 함수로 넘길 때 입력받은 리스트를 인덱스 노테이션을 이용해 범위를 지정해 넘겼는데 틀리는 경우가 생겼다.
- 음수:
books[:idx]
, 양수:books[N:idx - 1:-1]
였는데 이 경우 원소가 양수 한 개일 때 해당 원소를 포함하지 않는다. - 양수 리스트를
books[idx:][::-1]
로 수정해서 해결했다.
- 음수:
피드백
- 두 번째 에러를 해결하는데 진행상 오류를 찾지 못해서 시간이 오래 걸렸다.
- 채점할 때 케이스 통과가 꽤 많이 진행되고 끊긴 것을 보니 극단적인 예제에서 틀린 것 같긴 했는데 해당 예시를 좀 더 빠르게 떠올리고 테스트했으면 좋았을 것 같다.
2022.04.06 (JS)
메모리 | 시간 | 코드 길이 |
---|---|---|
9588 KB | 128 ms | 875 B |
단계 | 시작 시각 | 끝난 시각 | 걸린 시간 |
---|---|---|---|
문제 이해 | 16:00:29 | 16:01:48 | |
풀이 생각 | 16:01:52 | 16:04:09 | |
코딩 | 16:05:24 | 16:27:09 |
const fs = require("fs");
const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n");
function getLen(arr) {
const sorted = arr.sort((a, b) => b - a);
const len = [];
for (let i = 0; i < sorted.length; i += M) {
len.push(sorted[i]);
}
if (len.length) {
return [len.reduce((prev, curr) => prev + curr), len[0]];
} else return [0, 0];
}
function main() {
const pos = [];
const neg = [];
books.forEach((book) => {
if (book < 0) neg.push(Math.abs(book));
else pos.push(book);
});
const [posLen, posMax] = getLen(pos);
const [negLen, negMax] = getLen(neg);
return (posLen + negLen) * 2 - Math.max(posMax, negMax);
}
const [NM, lines] = input;
const [N, M] = NM.split(" ").map((n) => parseInt(n));
const books = lines.split(" ").map((n) => parseInt(n));
console.log(main());
참고 답안
from heapq import heappush, heappop
N, M = map(int, input().split(' '))
books = list(map(int, input().split(' ')))
pos= []
neg= []
largest = max(max(books), - min(books))
for i in books:
if i > 0:
heappush(pos, -i)
else:
heappush(neg, i)
res= 0
while pos:
res+= heappop(pos)
for _ in range(M - 1):
if pos:
heappop(pos)
while neg:
res+= heappop(neg)
for _ in range(M - 1):
if neg:
heappop(neg)
print(-res* 2 - largest)
아이디어 & 풀이
sort
대신 최대 힙을 이용해서 구현했다.
-
ps-python ps-js