알고리즘/백준

백준_1863 : 스카이라인 쉬운거 - C++

맏리믓 2023. 8. 5. 14:25

문제

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

 

1863번: 스카이라인 쉬운거

첫째 줄에 n이 주어진다. (1 ≤ n ≤ 50,000) 다음 n개의 줄에는 왼쪽부터 스카이라인을 보아 갈 때 스카이라인의 고도가 바뀌는 지점의 좌표 x와 y가 주어진다. (1 ≤ x ≤ 1,000,000. 0 ≤ y ≤ 500,000) 첫

www.acmicpc.net


문제 해석

- 밤에 태양이 질 때 보이는 건물의 윤곽을 스카이 라인이라 한다.

- 이 스카이 라인을 보고 건물이 최소 몇개 있는지 구하는 문제이다.

- 예시로 아래처럼 윤곽이 보인다면 건물이 3개 존재 하는데 다음과 같다.

..........
.....XX...
.XXX.XX...
XXXXXXXXXX
..........
.....XX...
.XXX.XX...
1111111111
..........
.....XX...
.222.XX...
X222XXXXXX
..........
.....33...
.XXX.33...
XXXXX33XXX

문제 풀이

- 입력을 받을 때는 2가지 종류가 있다.

 . 건물이 커지는 경우

 . 건물이 작아지는 경우

 . 윤곽이 바뀔 때만 입력으로 들어 오기 때문에 동일 한 경우는 없다.

 

- 이 때 건물의 크기가 커지는 경우는 다른 건물로 봐도 무방 하지만 작아지는 경우는 무조건 다른 건물로 보기 힘들다.

 . 아래 그림을 보면 건물의 크기가 3 에서 2로 줄었지만 1번칸과 3번 칸의 건물이 같은 건물일 가능성이 있기 때문이다.

 . 또한 문제에서 건물 개수의 최소를 구하라고 하였기 때문에 이는 같은 건물로 보는 것이 옳다.

 . 반대로 아래 그림은 크기가 줄었지만 1번과 3칸은 다른 건물이다.

 . 건물의 높이가 다르기 때문이다.

 

- 즉 정리 하자면 입력 값에서 건물의 크기가 늘었다면 다른 건물, 줄었다면 이 전의 건물들과 비교해서 건물의 수를 확인 하면 된다.

 

- 여기서 한가지 주의 할 점이 있는데 윤곽이 0 도 입력 된다는 점이다.

 . 아래 그림에선 3번 칸은 2번칸에서 높이가 줄었고 1번 칸의 높이와도 다르지만 높이가 0 이기 때문에 건물로 생각 하면 안된다.

 

- 스택을 통해 구현 하고 위 조건을을 적용 시키면 문제를 해결 할 수 있다.


코드

#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int N;
stack<int> s;
int ans = 0;

void solution(){
    cin >> N;
    while(N--){
        int x, y;
        cin >> x >> y;
        while(!s.empty() && s.top() > y){
            int del = s.top();
            s.pop();
            if(!s.empty() && s.top() == del) continue;
            if(del == 0) continue;
            ans += 1;
        }
        s.push(y);
        cout << s.size() << '\n';
    }

    while(!s.empty()){
        int tmp = s.top();
        s.pop();
        if(!s.empty() && s.top() == tmp) continue;
        if(tmp == 0) continue;
        ans += 1;
    }
    cout << ans << '\n';
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    solution();
}