코딩 테스트/Baekjoon

[백준] 1874. 스택 수열

배기니어 2021. 4. 12. 00:49

문제

스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다.

1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다. 이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자. 임의의 수열이 주어졌을 때 스택을 이용그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하라.

입력

첫 줄에 n (1 ≤ n ≤ 100,000)이 주어진다. 둘째 줄부터 n개의 줄에는 수열을 이루는 1이상 n이하의 정수가 하나씩 순서대로 주어진다. 물론 같은 정수가 두 번 나오는 일은 없다.

출력

입력된 수열을 만들기 위해 필요한 연산을 한 줄에 한 개씩 출력한다. push연산은 +로, pop 연산은 -로 표현하도록 한다. 불가능한 경우 NO를 출력한다.

 


주어진 수열을 만들기 위한 연산의 순서를 구하는 문제이다.

예제 입출력은 다음과 같다.

 

CASE INPUT OUTPUT
1 8
4
3
6
8
7
5
2
1
+
+
+
+
-
-
+
+
-
+
+
-
-
-
-
-
2 5
1
2
5
3
4
NO

 

연산은 push(+)와 pop(+) 두 가지이며, 스택에는 1부터 n까지의 수를 차례로 push한다.

첫 줄에 n이 주어지고 그 다음 수열이 주어지므로 반복문 안에서 주어진 수열에 따라 push할 지, pop할 지 결정한다.

 

n번의 반복문을 통해 다음 연산을 수행한다.

  1. 현재 항의 수가 스택에 push한 마지막 수보다 크다면 push한다. 이 때, 항의 수까지 스택에 push하고, count 변수로 마지막에 push한 수를 기록한다. 항의 수까지 스택에 push했다면 스택의 마지막 수를 pop하여 수열을 구성한다.
  2. 현재 항의 수가 스택에 push한 마지막 수보다 크지 않다면 pop한다. pop한 수가 현재 항의 수와 일치한다면 다음 반복문을 진행하고, 일치하지 않으면 구성할 수 없는 수열이므로 NO를 출력하며 반복문을 빠져나온다.

1번 예제 입력에서 n=8, 수열의 각 항을 a[i]라고 하자.

총 8번의 반복문에서 a[i]에 따라 연산을 수행한다.

1. i == 0

현재 스택에 push한 값이 없고 첫 항인 a[0]가 4이므로, 스택에 4까지 push한다. 그리고 pop하여 4를 수열로 구성해야 하므로 +,+,+,+,-의 연산이 수행된다.

2. i == 1

스택에 push한 마지막 값이 4이고 두 번째 항인 a[1]이 3이므로, 스택에서 pop한다. -의 연산이 수행된다.

3. i == 2

스택에 push한 마지막 값이 4이고 a[2]가 6이므로, 스택에 6까지 push한다. 이 때, 앞서 push했던 4 이후부터 push하도록 한다. 따라서 스택에 5,6을 push하고 6을 pop하므로 +,+,-의 연산이 수행된다.

4. i== 3

스택에 push한 마지막 값이 6이고 a[3]가 8이므로, 스택에 8까지 push한다. 스택에 7,8을 push하고 8을 pop하므로, +,+,-의 연산이 수행된다.

5. i == 4

스택에 push한 마지막 값이 8이고 a[4]가 7이므로, 스택에서 pop한다. -의 연산이 수행된다.

6. i == 5

스택에 push한 마지막 값이 8이고 a[5]가 5이므로, 스택에서 pop한다. -의 연산이 수행된다.

7. i == 6

스택에 push한 마지막 값이 8이고 a[6]가 2이므로, 스택에서 pop한다. -의 연산이 수행된다.

8. i == 7

스택에 push한 마지막 값이 8이고 a[7]가 1이므로, 스택에서 pop한다. -의 연산이 수행된다.

 

따라서 결과는 + + + + - - + + - + + - - - - -이다.

실행 과정을 그림으로 나타내면 다음과 같다.

 

 i == 0 i == 1 i == 2 i == 3
i == 4 i == 5 i == 6 i == 7

 

마찬가지 과정으로 예제 2를 실행하면 불가능한 경우임을 알 수 있다.

 

작성 코드!

n = int(input())
cnt = 0
stack = []
result = []

for _ in range(n):
    a = int(input())
    if a > cnt:
        while cnt != a:
            cnt += 1
            stack.append(cnt)
            result.append("+")
        stack.pop()
        result.append("-")
    else:
        b = stack.pop()
        result.append("-")
        if b != a:
            result = ["NO"]
            break
            
print("\n".join(result))

'코딩 테스트 > Baekjoon' 카테고리의 다른 글

[백준] 11004. K번째 수  (0) 2021.04.14
[백준] 2751. 수 정렬하기 2  (0) 2021.04.13
[백준] 7490. 0 만들기  (0) 2021.04.13
[백준] 2798. 블랙잭  (0) 2021.04.11
[백준] 2920. 음계  (0) 2021.04.11