[1874] 스택 수열

HeeSeong·2021년 7월 14일
0

백준

목록 보기
31/79
post-thumbnail

🔗 문제 링크

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


❔ 문제 설명


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

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

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


⚠️ 제한사항


  • 첫 줄에 n (1 ≤ n ≤ 100,000)이 주어진다.

  • 둘째 줄부터 n개의 줄에는 수열을 이루는 1이상 n이하의 정수가 하나씩 순서대로 주어진다.

  • 같은 정수가 두 번 나오는 일은 없다.



💡 풀이 (언어 : Java)


문제 설명을 보고도 잘 이해가 안가서 처음에 해맸고, 이해한 후에는 아무리 반례를 입력해도 맞는데 왜 틀렸다고 판정을 내리는지 몰라서 해맸다. 내가 짠 풀이는 처음의 정답 수열은 입력 순으로 큐에 담고, 이와 같은 수열을 만드는 건 스택에 쌓아서 만들었다. 그리고 큐의 맨 앞의 원소와 같은 값을 만날때까지 1부터 스택에 계속 쌓아올린다. 같은 값을 만나면 스택과 큐에서 모두 해당 원소를 제거해주고, 그 다음 원소도 같은지 비교해서 서로 다른 수가 나올때까지 제거해준다.
스택과 큐의 원소가 같은지 비교할 때 안의 원소는 Integer 객체이다. int가 아니기 때문에 단순 "==" 으로 비교하면 값이 아닌 주소값으로 비교해서 같은 숫자여도 false가 된다. 단순한건데 이걸 놓쳐서 계속 해맸다. 값으로 비교해주기위해 intValue()를 해주고 비교해주면 통과한다.

public class Main {
    private static String stackSequence(int n, Queue<Integer> input) {
        StringBuilder strBuilder = new StringBuilder();
        Stack<Integer> stack = new Stack<>();
        for (int i = 1; i <= n; i++) {
            int check = input.peek().intValue();
            if (i <= check) {
                strBuilder.append("+");
                strBuilder.append(System.getProperty("line.separator"));
                stack.push(i);
            }
            if (i == check) {
                // 안에 int가 아닌 Integer들이 들어서 intValue() 사용안하면 값이아닌 객체의 주소 같은지 비교가 됨
                // 웬만한 입력에서는 잘 돌아가는 이유는, 자바의 경우 -128부터 127까지의 Integer 객체는 미리 만들어두고
                // 이 범위 내의 값을 가질 경우 해당 객체를 사용하고, 그 외의 경우에만 새로운 객체를 만듭니다.
                while(input.peek().intValue() == stack.peek().intValue()) {
                    strBuilder.append("-");
                    input.poll();
                    stack.pop();
                    if (input.size() == 0) {
                        break;
                    }
                    strBuilder.append(System.getProperty("line.separator"));
                    if (stack.size() == 0) {
                        break;
                    }
                    if (input.peek().intValue() < stack.peek().intValue()) {
                        return "NO";
                    }
                }
            }
        }
        return strBuilder.toString();
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        Queue<Integer> input = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            input.offer(Integer.parseInt(br.readLine()));
        }
        System.out.println(stackSequence(n, input));
    }
}
profile
끊임없이 성장하고 싶은 개발자

0개의 댓글