문제
스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다.
1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다. 이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자. 임의의 수열이 주어졌을 때 스택을 이용해 그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하라.
입력
첫 줄에 n (1 ≤ n ≤ 100,000)이 주어진다. 둘째 줄부터 n개의 줄에는 수열을 이루는 1이상 n이하의 정수가 하나씩 순서대로 주어진다. 물론 같은 정수가 두 번 나오는 일은 없다.
출력
입력된 수열을 만들기 위해 필요한 연산을 한 줄에 한 개씩 출력한다. push연산은 +로, pop 연산은 -로 표현하도록 한다. 불가능한 경우 NO를 출력한다.
풀이
습관이 중요한거 같긴하다.
예전까지 ios::sync_with_stdio를 쓰지 않고 scanf, printf를 애용했었는데 cin.tie(0)으로 묶고 나서 scanf를 사용해서 문제를 틀렸다.
변경 후에도 시간 초과가 발생하였는데 cout에서 endl을 사용하고 안 하고의 차이로 시간 초과 여부가 결정되었다.
문제를 풀 때는 endl을 쓰지말고 꼭 "\n"을 사용하도록 하자.
문제는 +, - 여부를 담는 vector<char> ans 와 초반 배열 arr 과 stack을 사용하여 풀었다.
초반에 입력 받은 arr 배열이 stack에 1부터 n까지 push, pop을 해서 얻을 수 있는 값과 같아야한다.
따라서 for문을 돌면서 arr[i]를 꺼내고 해당 값을 stack에서 만들 수 있을 때까지 push, pop을 해야한다.
바로 cout을 하면 NO를 출력해야할 때 출력 오류가 발생하므로 vector에 +, -를 저장하도록 하였다.
num는 1부터 증가하는 값인데 num가 arr[i]보다 작거나 같다면 num를 증가시키면서 s에 push해준다.
만약 s.top이 arr[i]와 같다면 해당 값을 출력하고 같지 않다면 num가 arr[i]보다 크고 top에 있는 값이 arr보다 크므로 해당 배열을 만들 수 없다는 것이라 판단하여 "NO"를 출력한다.
코드
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<int> arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
stack<int> s;
vector<char> ans;
int num = 1;
for (int i = 0; i < n; i++) {
while (num <= arr[i]) {
s.push(num++);
ans.push_back('+');
}
if (s.top() == arr[i]) {
s.pop();
ans.push_back('-');
} else {
cout << "NO\n";
return 0;
}
}
for (char c : ans) {
cout << c << '\n';
}
return 0;
}
'dev > 코딩테스트' 카테고리의 다른 글
[BOJ - 1759] 암호 만들기 (2) | 2024.12.09 |
---|---|
[BOJ - 2841] 외계인의 기타 연주 (0) | 2024.12.09 |
[BOJ - 6603] 로또 (0) | 2024.12.09 |
[BOJ - 10799] 쇠막대 (0) | 2024.12.04 |
[BOJ - 3986] 좋은 단어 (0) | 2024.12.04 |