1874번: 스택 수열
1부터 n까지에 수에 대해 차례로 [push, push, push, push, pop, pop, push, push, pop, push, push, pop, pop, pop, pop, pop] 연산을 수행하면 수열 [4, 3, 6, 8, 7, 5, 2, 1]을 얻을 수 있다.
www.acmicpc.net
input되는 숫자의 갯수와 그 숫자들로 순서대로 수열을 하나 만들고, 그 숫자 오름차순으로 스택에다가 push를 하며 중간중간 pop을 하며 이 수열을 만들 수 있는가? 를 묻는 문제이다.
문제가 약간 어렵게 느껴질수도 있는데, 예제 1을 보면, 8 > 4 3 6 8 7 5 2 1 순으로 수열이 나열되어있다. 하지만 오름차순으로 push를 해야하기에 1 2 3 4 를 push하고 4를 pop하고, 3을 pop하면 수열의 첫째 둘쨰항인 4 3 이 나온다.
이런식으로 6을 만들기 위해 5 6 을 push한후 6을 다시 pop해야한다. 그렇다면 pop되지 않고 push만 하여 남은 숫자들을 나중에 쌓였던 스택의 순서대로 pop하여 수열을 만들 수 있는가를 묻는것이다.
처음 나의 접근은 주어지는 수열 자체의 구조에 집중을 했다. 예를들어 수열이 오름차순이거나 내림차순이면 자명하게 스택으로 수열을 만들 수 있다. 예제 1와 예제 2같은 일반적인 수열의 경우는 마지막 인덱스와 그 전 인덱스의 대소관계로 접근해봤지만 이는 반례가 생길 수 있는 가능성이 너무 많고, 코드로 짜기 쉽지가 않다.
두번째 접근은 일단 오름차순대로 push를 할 수 있는 것이니 위 접근 처럼 수열 자체에 집중을 하는것이 아닌, 주어지는 수열의 순서대로 스택에다가 push를 하는것이다.
예제 1의 첫번째 항은 4이다. 여기서 1 2 3 4 push를 한다. 즉 여기서 push를 하는 조건은 다음 항 (예제 1에선 3) 보다 클 조건에서 push를 해야겠다. (4까지 push를 한 후, 4를 pop하는 상황에서 다음 항이 5 이면 push를 해야하지만, 3이나 2면 pop을해야한다.
여기서 변수를 하나 설정하여 만약 첫째항까지의 push pop이 끝났다면, 첫째항을 변수로 담아, 이 첫째항보다 클때 push를 이어나간다. push를 한 후엔 변수를 다시 그 항의 정수로 초기화를 해야한다.
만약 첫째항보다 작다면 push를 하지 않고 pop을 한번 더 해야하는데, 이때 조건문을 하나 걸어줘야한다.
일단 pop을 한번 더 할때, 위의 예시로는 스택의 현상태는
3
2
1
을 이루고 있을 것이다. 이때 다음항 즉 둘째항이 3이 아닌 다른 숫자라면 pop을 한다면 필연적으로 3이 나올텐데, input된 수열의 둘째항이 3이 아닌 다른 숫자라면 ( 아마 1,2 둘 중에 하나겠다) 같은 수열의 구조로 만들 수 없기에 프로그램을 강제 종료한다.
package 스택과큐;
import java.io.*;
import java.util.*;
public class _1874_스택수열 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
Stack<Integer> stack = new Stack<Integer>();
int n = Integer.parseInt(br.readLine());
int start = 0;
while(n-- >0) {
int target = Integer.parseInt(br.readLine());
if(target>start) {
for(int i=start+1; i<=target; i++) {
stack.push(i);
sb.append("+").append('\n');
}
start = target;
}
//반복문이 돌 동안, stack의 맨 위의값이 target 즉 수열의 다음 값과 다를경우, stack이라는 구조때문에 손 쓸 수 있는 방법이없다.
else if(stack.peek() != target) {
System.out.println("NO");
return;
}
stack.pop();
sb.append("-").append('\n');
}
System.out.println(sb);
}
}
>> 문제에서 주어진 정보 그대로 코드를 짜면 되는 문제였다. 너무 복잡하게 수열을 일반화 하려해서 어렵게 풀었던것 같다.
'Algorithm_PS' 카테고리의 다른 글
백준 1158 <요세퍼스 문제> (0) | 2024.01.16 |
---|---|
백준 1406 <에디터> (1) | 2024.01.02 |
백준 2346 <풍선 터뜨리기> (0) | 2023.12.27 |
백준 11478 <서로 다른 문자열의 개수> (1) | 2023.12.08 |
백준 1269 <대칭 차집합> (0) | 2023.12.02 |