문제
소스코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include<iostream>
#include<vector>
bool CheckAbleBlock(std::vector<int>& ground, int index) {
//왼쪽 오른쪽 방향키
int lhs = index - 1;
int rhs = index + 1;
bool left{ false }, right{ false };
while (true) {
//범위 밖이면 flase
if (lhs < 0 || rhs >= ground.size())return false;
//둘다 만족하면 true
if (left && right)return true;
//더 큰 값이 있는지 찾기 위해 감소(왼쪽)
if (ground[lhs] <= ground[index]) {
--lhs;
}
else {
left = true;
}
//더 큰 값이 있는지 찾기 위해 증가(오른쪽)
if (ground[rhs] <= ground[index]) {
++rhs;
}
else {
right = true;
}
}
}
int main() {
int H{}, W{}, totalAdd{};
std::cin >> H >> W;
std::vector<int> ground;
for (int i = 0; i < W; ++i) {
int n{};
std::cin >> n;
ground.emplace_back(n);
}
for (int j = 0; j < H; ++j) {
for (int i = 0; i < W; ++i) {
//왼쪽과 오른쪽을 탐색해서 둘다 true가 나오면 삽입
if (CheckAbleBlock(ground, i)) {
//gruond 값 증가
ground[i]++;
//토탈 값 증가
totalAdd++;
}
}
}
std::cout << totalAdd << "\n";
}
|
후기
이 문제를 해결하기 위한 방법은 Two Pointer(투 포인터)이다. 투 포인터란 두 개의 포인터를 가지고 탐색하는 알고리즘이다.
먼저 H와 W 크기만큼 반복문을 돌면서 각 블록에 빗물이 쌓일 수 있는지 체크를 하면서 블록에 빗물이 쌓일 수 있는지 체크하기 위해 CheckAbleBlock() 함수를 통해 체크를 한다.
해당 함수에 들어오게 되면 먼저 해당하는 블록 Index에서 lhs(왼쪽), rhs(오른쪽) 두 개의 포인터를 가지고 탐색을 시작한다. 그 후 각자 탐색을 시작하면서 현재 블록보다 더 큰 블록이 있다면 bool 값(left, right)에 true를 아니라면 더 큰 게 있는지 체크하면서 증가 감소를 범위 안에 있을 때까지 반복한다.
문제의 구현보다는 어떻게 접근할 것인가 하는 부분에서 많은 시간을 소비했다.
해결하는데 걸린 시간: 30분
출처
문제 링크: 14719번: 빗물 (acmicpc.net)
관련 글(투 포인터)
[온라인 코딩/탐색(Search)] - [백준] 1806번 부분합
[온라인 코딩/탐색(Search)] - [백준] 2018번 수들의 합 5
[온라인 코딩/탐색(Search)] - [백준] 2003번 수들의 합 2
'온라인 코딩 > 탐색(Search)' 카테고리의 다른 글
[릿코드] Search Insert Position (0) | 2021.03.27 |
---|---|
[백준] 17352번 여러분의 다리가 되어 드리겠습니다! (0) | 2021.02.20 |
[백준] 1916번 최소비용 구하기 (0) | 2020.12.22 |
[백준] 10026번 적록색약 (0) | 2020.10.17 |
[백준] 5567번 결혼식 (0) | 2020.10.17 |