문제 설명
특정 지역에 물을 담을 수 있는 수조가 있습니다. 수조의 각 벽은 높이가 다릅니다. 비가 내리면 물이 담기게 될텐데,
각 벽 사이에 얼마나 많은 물이 담길 수 있는지를 구하는 문제입니다.
입력
첫 번째 줄에는 정수 N(1 ≤ N ≤ 100,000)이 주어집니다. N은 벽의 개수를 나타냅니다.
두 번째 줄에는 N개의 정수 h_i (1 ≤ h_i ≤ 1,000,000)가 주어지며,
이는 각 벽의 높이를 나타냅니다.
출력
한 줄에 물이 담길 수 있는 양을 출력합니다.
문제 예제
5
0 1 0 2 1 0 1 3 2 1 2 1
예제 출력:
6
문제 풀이 과정
이 문제를 풀기 위해서 우리는 두 개의 배열을 사용할 것입니다.
하나는 현재 위치에서 왼쪽에 있는 벽의 최고 높이를 저장하고, 또 하나는 오른쪽에 있는 벽의 최고 높이를 저장합니다.
1. 문제 분석
각각의 위치에서 담길 수 있는 물의 양은, 그 위치의 벽 높이보다 왼쪽과 오른쪽의 벽 높이 중 최소값에서 현재 벽 높이를 뺀 값입니다.
예를 들어, 위치 i에서 물의 양은 다음과 같이 계산할 수 있습니다:
water[i] = max(0, min(left_max[i], right_max[i]) - height[i])
여기서 left_max
는 i의 왼쪽 벽 중 최대 높이를, right_max
는 오른쪽 벽 중 최대 높이를 의미합니다.
2. 알고리즘 설계
우리는 다음과 같은 단계로 알고리즘을 설계할 수 있습니다.
- 입력을 받아온다.
- 왼쪽 벽의 최대 높이를 저장하는 배열
left_max
를 생성한다. - 오른쪽 벽의 최대 높이를 저장하는 배열
right_max
를 생성한다. - 각 위치에서 담길 수 있는 물의 양을 계산한다.
- 최종적으로 물의 총량을 출력한다.
3. 코드 구현
아래는 위의 알고리즘을 C#으로 구현한 코드입니다.
using System;
class Program
{
static void Main(string[] args)
{
int N = int.Parse(Console.ReadLine());
int[] height = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
// 왼쪽 최대 높이 배열
int[] left_max = new int[N];
left_max[0] = height[0];
for (int i = 1; i < N; i++)
{
left_max[i] = Math.Max(left_max[i - 1], height[i]);
}
// 오른쪽 최대 높이 배열
int[] right_max = new int[N];
right_max[N - 1] = height[N - 1];
for (int i = N - 2; i >= 0; i--)
{
right_max[i] = Math.Max(right_max[i + 1], height[i]);
}
// 물의 양 계산
int water = 0;
for (int i = 0; i < N; i++)
{
water += Math.Max(0, Math.Min(left_max[i], right_max[i]) - height[i]);
}
Console.WriteLine(water);
}
}
4. 코드 설명
위의 C# 코드에서 사용된 알고리즘은 다음과 같습니다.
-
int N = int.Parse(Console.ReadLine());
– N값을 입력받아 벽의 개수를 저장합니다. -
int[] height = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
– 높이 입력을 받아 배열로 변환합니다. -
left_max
배열은 왼쪽에서부터의 최대 높이를 저장합니다. 이를 위해 첫 번째 벽의 높이를 세팅한 후, 반복문을 돌며
각 벽의 높이를 비교하여 최대값을 저장합니다. -
right_max
배열도 마찬가지로 오른쪽에서부터 최대 높이를 저장합니다. - 마지막으로, 각 벽 위치에서 물이 담길 수 있는 양을 계산하여 총 물의 양을 구합니다.
5. 복잡도 분석
이 알고리즘의 시간 복잡도는 O(N)입니다. 벽의 개수 N에 비례하여 연산을 수행하므로 제공된
입력 범위 내에서 효율적으로 동작합니다. 공간 복잡도 또한 O(N)으로 두 개의 배열을 저장하기 위한 공간이 필요합니다.
결론
이번 글에서는 물의 양을 계산하는 문제를 C#으로 해결해 보았습니다. 알고리즘을 단계적으로 설계하고
구현하는 과정에서 코딩 테스트에서 자주 접할 수 있는 문제 유형들을 확인할 수 있었습니다.
이 강좌가 당신의 코딩 테스트 준비에 도움이 되기를 바랍니다.