[백준] 5430 AC

Bini by Bini·2023년 2월 24일
0

코테

목록 보기
17/24

문제

[골드5] https://www.acmicpc.net/problem/5430

해설 없이 스스로 풀었나요?

원소가 한자리인 경우에 대해서만 구현해 valueerror를 겪어 구글링 했음
재풀이 추천


아이디어

  1. R (reverse) 명령이 들어온다고 정말로 배열을 뒤집으면 안된다.
    R은 최대 10만번까지 수행될 수 있다. 따라서 R 명령을 구현할 때 핵심은 실제 원소를 뒤집지 않고도 뒤집힌 것과 같은 효과를 내도록 하는 것이다.

D 명령은 첫번째 수를 버리는 것이다. 따라서 배열의 가장 왼쪽 값을 꺼내야 한다.
이를 위해 나는 reverse라는 bool 변수를 두었다.
reverse의 횟수가 홀수이면 True로 뒤집어야 한다. 이를 실제로 뒤집지 않고 왼쪽에서 값을 꺼내는 것이 아닌 오른쪽에서 값을 꺼낼 수 있도록 pop() 함수를 이용했다.
짝수이면 False로 뒤집지 않고, 그대로 둘 수 있도록 하였다. 그리고 왼쪽에서 값을 꺼낼 수 있도록 popleft() 함수를 이용했다.

  1. 배열에 들어있는 수는 최대 100이다.
    처음에 풀이할 때 입력을 받아 파싱하여 리스트로 변환할 때 배열에 들어있는 수를 한자리수로만 생각하여 구현하였다.
    입출력 예시에 [42]로 두자리수가 있지만 이는 어차피 지워지는 원소이므로 주어진 예시에서는 잘 동작되는 것처럼 보일 수 있다.
    정확히 원소를 구분하기 위해서는, ","를 기준으로 분리하면 된다.
    (이때 입력된 문자열의 처음 "["과 끝 "]"을 파싱해낸 후 진행한다.)
  • 주의할 점
  1. 출력에서의 공백
    입출력 양식을 보면, error가 아닐 때 리스트로 출력되는 것을 보면 [1,2,3,5,8]과 같이 원소 사이에 공백이 없다. 공백의 유무까지 정확하게 고려해야 한다. 파이썬에서 print(list)를 하면 원소 사이의 공백까지 출력되므로 틀리게 된다.

  2. 빈 배열의 입력
    배열에 아무 값도 입력되지 않았을 때 따로 처리해주지 않으면 덱 안에 ''가 하나 있는 것으로(덱의 길이가 1)로 인식된다.
    따라서 빈배열의 경우 []로 처리해주어야 한다.

# 빈 배열 처리 안했을 때
print(s, q, len(q)) # 출력 : [''] deque(['']) 1

# 비교
k = deque([])
print(k, len(k)) # 출력 : deque([]) 0

풀이

from collections import deque
import sys

T = int(input())

for _ in range(T):
    p = sys.stdin.readline().rstrip()
    n = int(input())
    s = sys.stdin.readline().rstrip()[1:-1].split(",")
    q = deque(s)
    
    if n == 0: # 빈배열이면 []로 처리. 이 작업 안하면 deque에 ['']로 값이 하나 있는 것으로 인식됨
        q = []

    reverse = False
    error = False
    for i in range(len(p)):
        if p[i] == 'R':
            reverse = not reverse
        else: # D
            if len(q) == 0: # 큐가 비었다면
                print("error")
                error = True
                break
            if reverse == False: # 맨 앞에서 꺼내면 됨
                q.popleft()
            else:
                q.pop()
    if not error:
        if reverse:
            q.reverse()
        print("[" + ",".join(q) + "]")

처음에 답을 출력할 때

    if not error:
        if reverse:
            q.reverse()
        answer = list(q)
        a = '['
        if len(answer) == 0:
            a = '[]'
        for i in range(len(answer)):
            if i == len(answer)-1:
                a = a + str(answer[i]) + "]"
            else:
                a = a + str(answer[i]) + ","
        print(a)

이렇게 굉장히 복잡하게 출력했었다.

answer를 리스트화 하여 a에 하나하나 값을 붙여나가지 않고,
'구분자'.join(리스트)를 이용하면 빠르고 편하게 출력할 수 있다. 여기서는 공백이 없이 원소 사이에 쉼표만 넣어 출력하고 앞 뒤로 [ ] 만 붙이면 된다.
이때 reverse 해야 하는지 여부를 파악하고, 뒤집어야 하면 reverse를 한번 실행하고 이후 실행문을 실행하면 된다.


Comment

처음에 입출력 예시만 보고 각 원소가 한자리수라고만 생각하고 문자열을 파싱할 때

for i in range(n):
        print(s[2*i+1])
        q.append(int(s[2*i+1]))
    print(arr)
    print(q)

위와 같이 진행하였다. 추출해야 하는 부분이 모두 홀수번째에 위치했다고 가정하고 그 숫자들만 추출해 덱에 넣는 방식이었다.
주어진 입출력에 대해서는 잘 동작하였으나, 원소가 한자리수가 아닌 두자리, 세자리인 히든 케이스에 대해서는 런타임 에러 (ValueError)가 발생하였다. 뭐가 문제인지 모르고 ..구글링만 엄청 오래하다가 아래 참고로 달아놓은 레퍼런스를 보고 파악했다.

문제에서 주어진 범위와 조건을 잘 확인하자. 입출력 예시만 단편적으로 보지 말기 ..!

reverse를 매번 실행하는 것이 아닌, 명령의 횟수에 따라 bool값으로 True와 False로 값을 바꾸며 D 명령이 주어졌을 때와 최종적으로 답을 출력해야 할 때만 이를 고려하는 것은 스스로 잘 생각해냈다 !


참고

https://www.acmicpc.net/board/view/25456

profile
My Precious Records

0개의 댓글