https://www.acmicpc.net/problem/12789
12789번: 도키도키 간식드리미
인하대학교 학생회에서는 중간, 기말고사 때마다 시험 공부에 지친 학우들을 위해 간식을 나눠주는 간식 드리미 행사를 실시한다. 승환이는 시험 기간이 될 때마다 간식을 받을 생각에 두근두
www.acmicpc.net
풀이 :
- 정렬되어 있지 않은 수열을 스택의 방식을 이용해 정렬할 수 있는지 여부를 물어보는 문제
- 스택의 방식이란, last in first out으로, 제일 뒤에 들어간 요소가 제일 먼저 나오는 것
1 주어진 배열을 탐색하며 제일 작은 값이 나오기 전까지 스택에 넣어준다
2 제일 작은 값을 만나면 값을 빼준다
3 현재 인덱스에 있는 값이 직전에 빠진 값보다 1 클 경우, 현재 인덱스의 값도 빼준다
4 현재 인덱스에 있는 값이 직전에 빠진 값보다 2 이상 클 경우, 스택을 탐색하며 정렬되지 않는 값이 나올 때가지 스택에서 값을 뺀다
5 그리고 스택에 현재 인덱스의 값을 넣는다
6 배열의 탐색이 끝난 후 스택에 쌓인 값이 있다면, 스택을 탐색한다
7 쌓인 스택의 값을 하나씩 꺼냈을 때 정렬되지 않는다면 바로 break해준다 -> 정렬되지 않는 여부가 결정되는 유일한 부분
- 예제를 통해 스택의 변화를 살펴보자
5
5 4 1 3 2
for문{
1을 만나기 전까지 스택에 값을 넣는다
스택 : 5 4
1을 만나서 저장한다
스택 : 5 4
num : 1
3을 만났는데 저장된 1보다 2크고, 스택 제일 위에 있는 값도 4라서 3을 스택에 쌓는다
스택 : 5 4 3
num : 1
2를 만났고, 2는 1보다 1크기 때문에 num에 2를 넣어준다
스택 : 5 4 3
num : 2
for문 종료}
스택이 비어있지 않기 때문에 while문에 들어간다
while문{
스택 : 5 4 3
num : 2
스택의 제일 위에 있는 값 3은 num의 값 2보다 1크기 때문에 num에 3을 넣고,
스택에서 3을 빼준다
스택 : 5 4
num : 3
스택의 제일 위에 있는 값 4는 num의 값 3보다 1크기 때문에 num에 4를 넣고,
스택에서 4를 빼준다
스택 : 5
num : 4
스택의 제일 위에 있는 값 5는 num의 값 4보다 1크기 때문에 num에 5를 넣고,
스택에서 4를 빼준다
스택 :
num : 5
while문 종료}
만약 배열이 3 5 4 1 2로 되어있다면,
for문이 종료되었을 때 num에는 2, 스택에는 3 5 4가 들어있고, 4는 2보다 2 크기 때문에 정렬이 불가능해진다
코드 :
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
int main(){
cin.tie(NULL);
ios::sync_with_stdio(false);
int n, num = 0, arr[10005];
bool res = true; //정렬 여부를 나타낼 res변수
stack<int> line;
cin >> n;
for(int i=0; i<n; i++){
cin >> arr[i];
}
for(int i=0; i<n; i++){
if(arr[i] == num+1){ //현재 인덱스의 값과 num+1의 값이 같다면
num = arr[i]; //num의 값 변경
}else{
while(!line.empty()){ //스택에 쌓인 값이 있다면 들어가는 while문
if(line.top() == num+1){ //스택 제일 위에 있는 값이 num+1의 값과 같다면
num = line.top(); //num의 값 변경
line.pop(); //스택에서 값 삭제
}else{ //while문의 조건이 스택이 비어있지 않을 때이기 때문에, 무한 반복을 할 수 있다
break; //따라서 if문의 조건에 맞지 않으면 break로 탈출해줘야 한다
}
}
line.push(arr[i]); //현재 인덱스의 값을 스택에 넣어준다
}
} //스택이 비어있다면 밑의 while문에 들어가지 않고, res의 값 또한 변경되지 않아 Nice가 출력된다
while(!line.empty()){ //스택이 비어있지 않다면, 위의 while문과 같은 동작을 한다
if(line.top() == num+1){
num = line.top();
line.pop();
}else{
res = false; //다만 이 while문의 경우 조건에 맞지 않으면 더이상 정렬할 수 있는 방법이 없기 때문에
break; //res의 값을 변경하고 탈출한다
}
}
(res ? cout << "Nice\n" : cout << "Sad\n");
}
'PS_Baekjoon' 카테고리의 다른 글
[백준 C++] 17413번 : 단어 뒤집기 2 (0) | 2023.03.29 |
---|---|
[백준 C++] 9324번 : 진짜 메시지 (0) | 2023.03.28 |
[백준 C++] 11899번 : 괄호 끼워넣기 (0) | 2023.03.26 |
[백준 C++] 20365번 : 블로그2 (0) | 2023.03.25 |
[백준 C++] 21921번 : 블로그 (0) | 2023.03.24 |