본문 바로가기
ps

[백준] 22866 - 탑 보기

by kariskan 2022. 12. 5.

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

 

22866번: 탑 보기

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

www.acmicpc.net

 

원래 건물 높이를 다루는 문제는 스택 하나로 쉽게 풀 수 있다.

하지만, 이 문제는 현재 건물보다 높은 건물 모두(양쪽)를 구해야 하는 문제이다.

 

따라서 본인은 이 문제를 두 개의 스택을 이용해서 해결했다.

 

사실상 두 개의 스택이라고 해보았자, 인덱스만 바뀌는 거라서 크게 다를 게 없다.

그래서 왼쪽을 다루는 스택 l만 가지고 풀이를 해보겠다.

 

문제의 예시를 그림을 그려보자.

 

이러한 입력이 왼쪽부터 들어온다고 할 때, 스택을 어떻게 관리해야 할까?

 

맨 처음 입력에 3의 입력이 들어온다. 그러면 스택은 아래와 같이 된다.

 

그다음에는 7의 입력이 들어온다.

그런데 잘 생각을 해보면, 왼쪽에 존재하는 자신보다 높이가 큰 빌딩을 구하는데 이용되는 스택인데, 7의 입력이 들어온다면 높이 3의 빌딩은 의미가 없어진다. 왜냐하면 높이 7의 빌딩의 존재 때문에 이후의 모든 빌딩은 7 보다 작거나 같은 높이의 빌딩을 볼 수 없기 때문이다.

 

 

이 다음 1의 입력이 들어온다.

이 문제에서는 1보다 작은 입력이 없지만, 일단은 넣어두자.

 

 

이후 6, 3의 입력이 들어오게 되는데 6의 입력때문에 1의 빌딩은 의미가 없어지므로, 스택에서 pop() 된다.

 

 

이런 식으로 스택을 구성해가면 왼쪽에 현재 빌딩의 높이보다 큰 빌딩이 몇 개 있는지 구할 수 있다.

바로, 매 순간의 스택의 크기가 바로 해당한다.

 

오른쪽도 똑같이 구할 수 있다.

 

그런데 이 문제는 구해야 하는 값이 하나 더 있다.

바로 거리가 가장 가까운 건물 중 번호가 작은 건물이다.

 

이 부분은 바로 매 순간 스택의 top의 번호이다.

생각해보면, 스택에는 항상 가까운 순서대로 채워지고, 항상 현재 건물의 높이보다 큰 건물의 번호가 존재하기 때문이다.

 

구현은 다음과 같다.

 

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

stack<pair<int, int>> l, r;
pair<int, int> ans[100001];
int inp[100001];

int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		int a;
		cin >> a;
		inp[i] = a;

		while (!l.empty() && a >= l.top().first)
		{
			l.pop();
		}
		if (!l.empty())
		{
			ans[i].second = l.top().second;
		}
		l.push({a, i});
		ans[l.top().second].first += l.size() - 1;
	}

	for (int i = n; i >= 1; i--)
	{

		while (!r.empty() && inp[i] >= r.top().first)
		{
			r.pop();
		}
		if (!r.empty())
		{
			if (ans[i].second == 0 || abs(i - ans[i].second) > abs(i - r.top().second))
				ans[i].second = r.top().second;
		}
		r.push({inp[i], i});
		ans[r.top().second].first += r.size() - 1;
	}

	for (int i = 1; i <= n; i++)
	{
		if (ans[i].first == 0)
		{
			cout << ans[i].first << '\n';
			continue;
		}
		cout << ans[i].first << ' ' << ans[i].second << '\n';
	}
}

'ps' 카테고리의 다른 글

[백준] 22954 - 그래프 트리 분할  (0) 2022.12.28
[백준] 13144 - List of Unique Numbers  (0) 2022.12.28
[백준] 1799 - 비숍  (0) 2022.11.11
[백준] 1477 - 휴게소 세우기  (0) 2022.11.11
[백준] 3079 - 입국심사  (0) 2022.11.08

댓글