BOJ_5430 AC
- TOC {:toc}
이 글은 백준 온라인 저지의 5430번 문제를 파이썬(Python)으로 풀이한 것을 모아놓은 글입니다.
일종의 연습 기록이며 제가 정답을 받은 코드와 참고할만한 다른 코드를 같이 기록합니다. 필요한 경우 코드에 대한 해설을 기록합니다만 코드는 통과했어도 해설은 틀릴 수 있기 때문에 가볍게 참고해주시길 부탁드립니다. 피드백은 편하신 방법으로 자유롭게 주시면 감사하겠습니다.
2021.04.27
메모리 | 시간 | 코드 길이 |
---|---|---|
107992 KB | 1332 ms | 501 B |
단계 | 시작 시각 | 끝난 시각 | 걸린 시간 |
---|---|---|---|
문제 이해 | 21:39:11 | 21:40:53 | |
풀이 생각 | 21:41:05 | 21:56:13 | |
코딩 | 21:56:16 | 22:26:40 | |
디버깅 | 22:46:42 | 22:54:22 |
import sys
from collections import deque
input = lambda: sys.stdin.readline().rstrip()
for _ in range(int(input())):
# 수행할 함수
p = input()
# 배열에 들어 있는 수의 개수
n = int(input())
# 배열
x = deque(eval(input()))
# reverse 여부
is_reverse = False
for m in p:
if m == "R":
# is_reverse를 토글 시킨다.
is_reverse = not is_reverse
elif x:
# reverse 상태이면 pop, 아니면 popleft 한다.
x.pop() if is_reverse else x.popleft()
else:
print("error")
break
else:
# is reverse가 True이면 x를 reverse 시킨 뒤 형식에 맞춰 출력한다.
print(f"[{','.join(map(str, reversed(x) if is_reverse else x))}]")
# 시간 초과
import sys
from collections import deque
input = lambda: sys.stdin.readline().rstrip()
for _ in range(int(input())):
p = input()
n = int(input())
x = eval(input())
for m in p:
if m == "R":
x.reverse()
elif x:
x.popleft()
else:
print("error")
break
else:
print(f"[{','.join(map(str, x))}]")
아이디어 & 풀이
eval()
을 사용해 입력을 배열 형태로 받은 뒤 이를 큐로 만든다.
is_reverse
상태를 바꿔가면서 첫 번째나 가장 마지막 원소를 pop 해나간다.
디버그
- 배열 형태로 입력받는 원소를
split()
시키면[1
,2
, …,n]
이기 때문에split()
후 첫, 끝 원소를slice()
하지 말고 애초에[
,]
를strip()
시켜야 한다. - deque + 내장 함수(e.g.,
reverse()
를 이용했더니 시간초과된다.- 매번
reverse()
를 하지 말고 reverse 여부를 저장해pop()
popleft()
를 알맞게 사용하고 필요할 경우 출력할 때만 reverse 시키도록 수정했다.
- 매번
피드백
-
popleft()
자체도 리스트가 커지면 시간이 오래 걸리기 때문에 양쪽에서 직접pop()
을 하는 것보다 slice를 이용하는 것이 훨씬 빠르다.popleft()
를 할 때는i
를pop()
을 할 때는j
를 1씩 증가시킨 뒤[i:n-j]
로 slice한다.- 참고 답안으로 채점한 결과
메모리 시간 코드 길이 39348 KB 152 ms 527 B -
[]
를 입력했을 때[
,]
을strip()
해도 빈 문자(''
)를 반환해서x
가 빈 문자를 원소로 갖게 되는 문제가 있었다. -
순회할 때마다 조건에 따른 동작을 있는 그대로 이행하지 말고, 다른 방식으로 저장해놨다가 한 번에 처리할 수 있도록 사고하는 연습이 필요한 것 같다.
참고 답안
import sys
input = lambda: sys.stdin.readline().rstrip()
for _ in range(int(input())):
# 명령을 입력받은 뒤 연속된 RR은 제거한다.
p = input().replace("RR", "")
n = int(input())
# i, j는 입력받을 배열을 slice 하기 위한 인덱스,
# is_reverse는 reverse 여부이다.
i, j, is_reverse = 0, 0, False
for f in p:
# 명령이 R이면
if f == "R":
# is_reverse를 전환한다.
is_reverse = not is_reverse
elif f == "D":
# reverse가 아니면
if not is_reverse:
# i(앞쪽 인덱스)를 1 증가시킨다.
i += 1
# reverse 상태이면
else:
# j(뒤쪽 인덱스)를 1 증가시킨다.
j += 1
# 배열을 입력받는다.
# [1:-1]: 괄호를 제거하고
# split(,): 각 원소를 ,로 구분해 나눈 뒤,
# [i : n - j]: 위에서 pop 한 만큼 양 끝을 slice 한다.
x = input()[1:-1].split(",")[i : n - j]
# 양 끝을 제거한 횟수가 입력받은 배열의 원소보다 많으면
if i + j > n:
# error를 출력한다.
print("error")
else:
print("[" + ",".join(x[::-1] if is_reverse else x) + "]")
아이디어 & 풀이
RR
이 연속으로 나오면 변하는 것이 없어서, 명령을 입력받을 때 RR
을 제거한다.
배열을 입력받을 때 [
, ]
을 제거하기위해 strip()
이 아닌 slice notation을 이용한다.
[1:-1]
로 양 끝을 제거할 수 있다.
-
ps-python