Notice
Recent Posts
Recent Comments
Link
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

mo1lusca의 블로그

[백준] 6198 옥상 정원 꾸미기 - C++ 본문

PS

[백준] 6198 옥상 정원 꾸미기 - C++

mo1lusca 2025. 6. 2. 01:39

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


로직을 짜려고 엄청 노력했다..

금단의 방법인 그림 그리기까지 써가며 풀었다.


문제를 이해하는 방식을 바꾸어야 한다.

높은 빌딩에서 자신보다 낮은 빌딩의 수를 세는 게 아니라

낮은 빌딩에서 자신을 볼 수 있는 높은 빌딩의 수를 세어주어야 한다.

 

stack을 top부터 뽑아가며,

top이 자신보다 낮다면? -> 자신을 볼 수 없으니 pop

top이 자신보다 높다면? -> top아래의 것들도 자신보다 높을 테니

자신보다 높은 빌딩의 수인 stack의 size(들어있는 원소의 개수)를 result에 더하고 자신을 push

 

위 로직대로 코드를 짰다.

빌딩의 개수와 높이가 딱 봐도 커서 맘 편하게 long long int를 사용했다.


#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
int main() {
	long long int result = 0;
	stack<int> stk;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int input;
		cin >> input;
		while (!stk.empty()) {
			if (stk.top() > input) {
				result += stk.size();
				break;
			}
			stk.pop();
		}
		stk.push(input);
	}
	cout << result;
	return 0;
}

 


 

 

사실 stack을 사용해서 풀기 전에, stack을 안 쓰고도 풀 수 있을 것 같아서

메모이제이션으로 푼 방법이 있긴 하다.

빌딩을 오른쪽부터 선택해서 자신이 볼 수 있는 빌딩의 개수를 메모하고.. 이런 식으로 진행된다.

어휘력이 안 좋으니 차근차근 읽기를 바란다..

 

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
	vector<int> height;
	long long int result = 0;
	int n;
	cin >> n;
	vector<int> memo(n, 0);
	for (int i = 0; i < n; i++) {
		int tmp;
		cin >> tmp;
		height.push_back(tmp);
	}
	for (int i = n - 2; i >= 0; i--) {
		int cur = i;
		memo[cur] = 0;
		int j = cur + 1;
		while (j < n && height[cur] > height[j]) {
			memo[cur] += memo[j] + 1; // <1>
			j += memo[j] + 1; // <2>
		}
		result += memo[cur];
	}
	cout << result << endl;
	return 0;
}


입력받은 빌딩의 높이를 저장할 벡터 height,

index번째 빌딩에서 볼 수 있는 빌딩의 수를 메모하는 벡터 memo(0으로 초기화됨)를

선언해 주었다.

 

첫 번째 for문은 그저 값을 입력받는 용도이다.

두 번째 for문은 height 벡터의 값을 오른쪽부터 선택하게 한다. = 오른쪽부터 왼쪽 빌딩을 차례로 선택한다.

현재 선택한 index를 알아보기 쉽게 cur로 새로 선언한다.

j는 cur번째 빌딩에서 바라볼 수 있는 빌딩의 index이다. (일단 cur번째 빌딩 바로 앞 빌딩의 index로 잡는다.)

 

while문의 조건식은 j가 벡터의 범위 안에 있게 하고, j번째 빌딩이 cur번째 빌딩보다 작을 때에만 이하의 코드를 실행하게 한다.

<1> : cur번째 빌딩이 볼 수 있는 건물 수에다가 j번째 건물이 볼 수 있는 건물 수 + 1을 더한다.

--->>> 왜냐하면, j번째 빌딩은 cur번째 빌딩보다 낮아서(while문 조건을 통과했으니) j번째 빌딩이 볼 수 있는 빌딩은 cur번째 빌딩도 볼 수 있다. 또한 cur번째 빌딩은 j번째 빌딩도 포함해서 볼 수 있으므로 + 1 해주었다.

<2> : j(index를 나타냄)에 j가 볼 수 있는 값 + 1을 더해준다.

--->>> 왜냐하면, j번째 빌딩이 볼 수 "없는" 빌딩을, cur번째 빌딩은 볼 수 있을 수도 있기 때문이다.

따라서 j번째 빌딩이 볼 수 있는 빌딩의 수 + 1 값을 j값에 더해 while문 조건을 한번 더 검사시킨다.

(j값을 알맞은 위치로 점프시킨다? 고 생각하면 될 것 같다.)

 

이후 현재 선택한 빌딩이 볼 수 있는 빌딩의 수를 result에 더하고,

모든 빌딩을 돌았다면 result를 출력한다.


처음부터 stack 썼으면 편하게 풀었을 것을

괜히 오기 부려서 오래 걸린 것 같다.........


 

'PS' 카테고리의 다른 글

[백준] 2606 바이러스 - C++  (1) 2025.06.03
[백준] 1260 DFS와 BFS - C++  (0) 2025.06.03
[백준] 14729 칠무해 - C++  (0) 2025.06.01
[백준] 1966 프린터 큐 - C++  (0) 2025.06.01
[백준] 3986 좋은 단어 - C++  (0) 2025.06.01