[백준 / C언어] 14719번: 빗물

728x90
728x90

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

 

14719번: 빗물

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치

www.acmicpc.net

14719번 문제 설명 1
14719번 문제 설명 2

 

난이도: solved.ac 골드 5

 

알고리즘 분류


구현, 시뮬레이션, 투포인터

 

접근 방법


물이 차려면 양쪽의 높이보다 더 낮은 높이를 가져야 한다.

이때 차는 물은 양쪽의 높이에서 더 낮은 쪽의 높이를 가진다.

접근 방법 설명

그리고 항상 특정 지점을 둘러싼 곳에서, 두 번째로 높은 지점의 높이로 물이 찬다.

아래 그림에서 1번부터 5번 사이의 구간을 보자.

1번부터 5번 사이에서 두 번째로 높은 지점은 1번 지점인데, 1번부터 5번 사이에서 1번 지점보다 더 낮은 지점은 1번의 높이까지 물이 찬다.

5번부터 8번 사이의 구간도 마찬가지다.

5번부터 8번 사이 중 두 번째로 높은 지점은 8번 지점인데, 그 사이에서 8번보다 낮은 지점은 8번의 높이까지 물이 찬다.

접근 방법 설명 2

 

구현


위의 성질을 이용해 양 끝에 포인터 left와 right를 두고, left와 right 중 더 낮은 쪽의 높이까지 물을 채웠다.

그리고 더 낮은 쪽에서 포인터를 가운데 쪽으로 한 칸 이동시켜 left >= right가 될 때까지 위의 과정을 반복하였다.

 

코드


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define Min(a,b) ((a)<(b)?(a):(b))

int main() {
	int H, W, cnt = 0;
	scanf("%d %d", &H, &W);
	int* arr = (int*)calloc(W, sizeof(int));
	for (int i = 0; i < W; i++)
		scanf("%d", &arr[i]);

	int left = 0, right = W - 1, min, start, end;
	while (left < right) {
		min = Min(arr[left], arr[right]);
		start = left + 1;
		end = right;
		while (start < end) {
			if (arr[start] < min) {
				cnt += min - arr[start];
				arr[start] = min;
			}
			start++;
		}
		if (min == arr[left])
			left++;
		else
			right--;
	}
	printf("%d", cnt);
	free(arr);
	return 0;
}
반응형