일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준 #BOJ #1697
- BOJ20444
- 백준2141
- 백준11404
- 1520내리막길
- BOJ9663
- BOJ11404
- boj
- 생활코딩
- BOJ14719
- github_actions
- BOJ2629
- 색종이와가위
- 이분탐색
- BOJ2110
- BOJ11066
- BOJ14501
- 백준
- 백트래킹
- BOJ1753
- BOJ2805
- BOJ1931
- BOJ11729
- DP
- 프로그래머스 #무지의먹방라이브 #C++
- 백준2533
- 재귀
- 백준2110
- BFS
- html
- Today
- Total
poksul_log
# 14719. 빗물 본문
관련 알고리즘 : 구현, 시뮬레이션
문제 링크 : https://www.acmicpc.net/problem/14719
14719번: 빗물
첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치
www.acmicpc.net
해결 과정
2차원 세계의 블록이 있고, 세로 길이 H(H>=1)와 가로 길이 W(W<=500)가 주어진다.
바닥은 항상 막혀 있다고 하였으므로 양 옆이 한칸이라도 막혀있다면 빗물이 고일 수 있지만,
문제에서 제시한 예제 3을 보면 블록 높이가 0 0 0 2 0 일 때 고인 빗물이 0 이므로
가장 왼쪽과 가장 오른쪽 부분에는 벽이 존재하지 않아 빗물이 고일 수 없음을 알 수 있다.
즉,
양 극단의 경우
- 블록이 존재 >> 블록 때문에 빗물이 고일 수 없음
- 블록이 존재하지 않음 >> 양 극단은 바닥처럼 벽이 막혀 있지 않기 때문에 빗물이 고일 수 없음
이 2가지 경우가 존재하고, 어떤 경우에도 빗물이 고일 수 없다.
따라서, 가로가 1~W까지 존재한다고 할 때, 빗물은 2~(W-1) 부분에만 존재할 수 있다.
예시를 만들어 해결 과정을 생각해보자.
각 가로길이 n당 있는 블록의 높이를 h(n)이라 하면,
각 Wn(1<=n<=7) 에 있는 빗물이 고일 수 있는 최대높이 maxH(n)는
maxH(n) = min(Wn의 좌측 블록 h중 최대, Wn의 우측 블록 h 중 최대) 라고 할 수 있음을 알 수 있다.
그렇다면, 해당 Wn에 고인 빗물은 maxH(n) - h(n) ( maxH(n) >= h(n) )이라고 할 수 있다.
이를 위 예시에 적용해보면,
- W2에서 h(2) = 0. maxH(2) = 4 → 4-0 = 4
- W3에서 h(3) = 2. maxH(3) = 4 → 4-2 = 2
- W4에서 h(4) = 6. maxH(4) = 4 인데 h(4) > maxH(4) 이므로 0
- W5에서 h(5) = 1. maxH(5) = 5 → 5-1 = 4
- W6에서 h(6) = 3. maxH(5) = 5 → 5-3 = 2
사진 속 예시의 빗물 양과 일치함을 알 수 있다.
C++ 코드
#include <iostream>
#include <algorithm>
#define MAX 501
using namespace std;
int h, w; // 세로길이 h, 가로길이 w
int height[MAX]; // 각 가로 당 블럭높이
int res = 0; // 총 빗물 양
void rain()
{
int leftMax;
int rightMax;
for (int i = 2; i < w; i++)
{
leftMax = height[i];
rightMax = height[i];
for (int j = 1; j < i; j++) // 좌측 블록 최대높이 구하기
{
leftMax = max(leftMax, height[j]);
}
for (int j = i + 1; j <= w; j++)
{
rightMax = max(rightMax, height[j]); // 우측 블록 최대높이 구하기
}
res += ( min(leftMax, rightMax)-height[i] ); // 빗물 최대 높이 구하기
}
cout << res;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> h >> w;
for (int i = 1; i <= w; i++)
{
cin >> height[i];
}
rain();
return 0;
}
'Coding Test > BOJ' 카테고리의 다른 글
# 2629. 양팔저울 (0) | 2022.08.28 |
---|---|
# 20444. 색종이와 가위 (0) | 2022.08.14 |
# 11729. 하노이 탑 이동 순서 (0) | 2022.07.31 |
# 11404. 플로이드 (0) | 2022.07.24 |
# 14501. 퇴사 (0) | 2022.07.17 |