코딩문제풀이/Baekjoon

[Java] 백준 22866번 : 탑 보기

코딩하는 포메라니안 2023. 6. 9. 15:32

문제

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

 

22866번: 탑 보기

3번째 건물에서 볼 수 있는 건물은 2, 4, 8번째 건물로 총 3개를 볼 수 있다. 그 중 3번째 건물과 가장 가까운 건물은 2, 4번째 있는 건물로 이 중 번호가 작은 번호인 2가 답이 된다.

www.acmicpc.net

 

 

풀이과정

stack을 활용하여 왼->오, 오->왼으로 각각 순회하면서 자신의 왼쪽 혹은 오른쪽으로 옆면을 볼 수 있는 건물을 찾는다.stack에는 데이터가 내림차순으로 남게 하여, 자신보다 큰 건물의 수는 stack의 크기와 동일하게 하면 된다.따라서, 자신보다 작은 값은 모두 pop시키고, 남은 stack크기를 자신이 볼 수 있는 건물 수에 더해주면 된다. 이때, stack의 top에 있는 값이 자신 양 옆에서 볼 수 있는 건물 번호가 되므로, 왼쪽 혹은 오른쪽 중 어느 것이 더 가까운지만 체크한다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());

        int[] h = new int[N + 1];
        int[] cnt = new int[N + 1], near = new int[N + 1];
        Stack<Integer> stack;

        //init
        for(int i=1; i<=N; i++){
            h[i] = Integer.parseInt(st.nextToken());
            near[i] = -100_000;
        }

        //left
        stack = new Stack<>();
        for(int i=1; i<=N; i++){
            while(!stack.isEmpty() && h[stack.peek()] <= h[i]){
                stack.pop();
            }
            cnt[i] = stack.size();
            if(cnt[i] > 0) near[i] = stack.peek();
            stack.push(i);
        }

        //right
        stack = new Stack<>();
        for(int i=N; i>0; i--){
            while(!stack.isEmpty() && h[stack.peek()] <= h[i]){
                stack.pop();
            }
            int s = stack.size();
            cnt[i] += s;
            if(s > 0 && stack.peek()-i < i-near[i]) near[i] = stack.peek();
            stack.push(i);
        }

        //result
        StringBuilder sb = new StringBuilder();
        for(int i=1; i<=N; i++){
            sb.append(cnt[i]);
            if(cnt[i] > 0){
                sb.append(" ").append(near[i]);
            }
            sb.append("\n");
        }
        System.out.println(sb);
    }
}