본문 바로가기
Algorithm/Python

[BOJ] 5430번 : AC [G5]

by 코코형아 2023. 2. 12.

https://www.acmicpc.net/problem/5430

 

5430번: AC

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

www.acmicpc.net

문제

선영이는 주말에 할 일이 없어서 새로운 언어 AC를 만들었다. AC는 정수 배열에 연산을 하기 위해 만든 언어이다. 이 언어에는 두 가지 함수 R(뒤집기)과 D(버리기)가 있다.

함수 R은 배열에 있는 수의 순서를 뒤집는 함수이고, D는 첫 번째 수를 버리는 함수이다. 배열이 비어있는데 D를 사용한 경우에는 에러가 발생한다.

함수는 조합해서 한 번에 사용할 수 있다. 예를 들어, "AB"는 A를 수행한 다음에 바로 이어서 B를 수행하는 함수이다. 예를 들어, "RDD"는 배열을 뒤집은 다음 처음 두 수를 버리는 함수이다.

배열의 초기값과 수행할 함수가 주어졌을 때, 최종 결과를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. T는 최대 100이다.

각 테스트 케이스의 첫째 줄에는 수행할 함수 p가 주어진다. p의 길이는 1보다 크거나 같고, 100,000보다 작거나 같다.

다음 줄에는 배열에 들어있는 수의 개수 n이 주어진다. (0 ≤ n ≤ 100,000)

다음 줄에는 [x1,...,xn]과 같은 형태로 배열에 들어있는 정수가 주어진다. (1 ≤ xi ≤ 100)

전체 테스트 케이스에 주어지는 p의 길이의 합과 n의 합은 70만을 넘지 않는다.

출력

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

 

예제 입력 1 

4
RDD
4
[1,2,3,4]
DD
1
[42]
RRD
6
[1,1,2,3,5,8]
D
0
[]

예제 출력 1 

 

[2,1]
error
[1,2,3,5,8]
error
 
 

내 풀이

기본적으로 덱을 사용하여 풀이하였다.

문제자체는 직관적이고 쉽게 느껴져서 왜 골드5지?라는 생각을 했지만 바로 시간초과의 벽에 막혀버려 처음부터 계속 고민하였다.

 

덱을 사용하더라도 deque.reverse()의 시간복잡도가 O(n)으로 계속해서 'R'로 배열의 수를 뒤집으면 시간복잡도가 기하급수적으로 높아질 수 밖에 없기 때문에 reverse함수를 최소화 시키는 방향으로 구현하였다.

'R'이 나올때마다 count를 해주어 'D'가 나왔을 때, count가 2의 배수이면 배열이 원상태이기 때문에 가장 왼쪽 수를 빼주고(xd.popleft()) 2의 배수가 아니면 배열이 뒤집힌 상태이기 때문에 가장 오른쪽 수를 빼주었다(xd.pop())

그리고 마지막에 딱 한번 reverse함수를 호출하여 배열을 뒤집어주었다.

 

그러고도 16%에서 계속 틀렸습니다가 나왔고, 반례도 계속 찾아보았지만 아무리 봐도 맞는 코드 같았다.

 

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

 

글 읽기 - ★☆★☆★ [필독] AC FAQ ★☆★☆★

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

해답은 위 게시글 11번에서 찾았다.

배열을 출력하면 보통 [1, 2, 3, 4, 5]와 같이 숫자들 사이사이마다 공백이 함께 출력된다.

하지만 위 예제출력에서 확인할 수 있듯이, 숫자들 사이에 공백이 있어선 안되는 것이 포인트였다.....

join함수를 사용하여 수 사이의 공백을 제거하여 문자열로 출력해 주어 해결하였다.

 

# AC
import sys
from collections import deque
input = sys.stdin.readline

case = int(input())
ans = []

for i in range(case):
    fx = input().rstrip()
    n = int(input())
    x = input().rstrip()
    x = x[1:-1]
    if len(x) != 0:
        x = list(map(int, x.strip().split(",")))


    xd = deque(x)

    count = 0
    tag = 0
    for j in range(len(fx)):
        if fx[j] == 'R':
            count += 1
           
        elif fx[j] == 'D':
            if len(xd) == 0:
                ans.append('error')
                tag = 1
                break
            if count%2 == 0: # 짝수번만큼 뒤집었으면 왼쪽수 제거
                xd.popleft()
            else: #홀수번만큼 뒤집었으면 오른쪽수 제거
                xd.pop()

    if count%2 != 0: #홀수번만큼 뒤집었으면 최종적으로 뒤집어진상태
        xd.reverse()

    if tag != 1:
        ans.append(list(xd))

for i in range(len(ans)):
    if ans[i] != 'error':
        print('[' + ','.join(map(str, ans[i])) + ']') #수 사이에 공백이 안생기게 하는방법
    else:
        print(ans[i])

 

 

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 2133번 : 타일 채우기 [G4]  (2) 2023.08.21
[BOJ] 1562번 : 계단 수 [G1]  (0) 2023.07.27
[파이썬] List, Tuple, Set, Dictionary  (0) 2023.07.05