백준 14719번 (빗물, C++, Simulation) [BAEKJOON]

빗물

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

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초256 MB106645888465955.770%

문제

2차원 세계에 블록이 쌓여있다. 비가 오면 블록 사이에 빗물이 고인다.

비는 충분히 많이 온다. 고이는 빗물의 총량은 얼마일까?

입력

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500)

두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치부터 차례대로 W개 주어진다.

따라서 블록 내부의 빈 공간이 생길 수 없다. 또 2차원 세계의 바닥은 항상 막혀있다고 가정하여도 좋다.

출력

2차원 세계에서는 한 칸의 용량은 1이다. 고이는 빗물의 총량을 출력하여라.

빗물이 전혀 고이지 않을 경우 0을 출력하여라.

예제 입력 1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
4 4
3 0 1 4
4 4 3 0 1 4
4 4
3 0 1 4

예제 출력 1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
5
5
5

예제 입력 2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
4 8
3 1 2 3 4 1 1 2
4 8 3 1 2 3 4 1 1 2
4 8
3 1 2 3 4 1 1 2

예제 출력 2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
5
5
5

예제 입력 3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
3 5
0 0 0 2 0
3 5 0 0 0 2 0
3 5
0 0 0 2 0

예제 출력 3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0
0
0

출처

University > 충남대학교 > 생각하는 프로그래밍 대회  D번

  • 문제를 만든 사람: isku

알고리즘 분류


아래서부터 블록과 블록 사이에 공간을 카운트하여 고여있는 빗물의 칸을 계산할 생각

좌/우 를 확인하면서 빈공간을 체크하면 좋을 것 같다.

입력 확인 코드

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <iostream>
using namespace std;
// 가로, 세로의 길이는 최대치가 500
constexpr auto MAX = 500;
// 0 빈공간, 1 블록
int map[MAX][MAX];
// 가로 / 세로
int H, W, tempOne, tempTwo;
// 빗물의 개수
int rainwaterCnt = 0;
bool debugbool = true;
// 시각적인 디버깅을 위한 함수
void VisualDebug()
{
cout << "\n";
for (int i = 0; i < W; i++)
{
for (int j = 0; j < H; j++)
{
cout << map[i][j] << " ";
}
cout << "\n";
}
}
// 문제의 입력을 받는 함수
void ReceiveInput()
{
cin >> H >> W;
tempTwo = W;
for (int i = 0; i < tempTwo; i++)
{
cin >> tempOne;
for (int j = 0; j < tempOne; j++)
{
map[i][j] = 1;
}
}
}
// 초기화를 진행하는 함수
void Initialization()
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
map[i][j] = 0;
}
}
}
int main()
{
Initialization();
ReceiveInput();
if (debugbool) { VisualDebug(); }
return 0;
}
#include <iostream> using namespace std; // 가로, 세로의 길이는 최대치가 500 constexpr auto MAX = 500; // 0 빈공간, 1 블록 int map[MAX][MAX]; // 가로 / 세로 int H, W, tempOne, tempTwo; // 빗물의 개수 int rainwaterCnt = 0; bool debugbool = true; // 시각적인 디버깅을 위한 함수 void VisualDebug() { cout << "\n"; for (int i = 0; i < W; i++) { for (int j = 0; j < H; j++) { cout << map[i][j] << " "; } cout << "\n"; } } // 문제의 입력을 받는 함수 void ReceiveInput() { cin >> H >> W; tempTwo = W; for (int i = 0; i < tempTwo; i++) { cin >> tempOne; for (int j = 0; j < tempOne; j++) { map[i][j] = 1; } } } // 초기화를 진행하는 함수 void Initialization() { for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { map[i][j] = 0; } } } int main() { Initialization(); ReceiveInput(); if (debugbool) { VisualDebug(); } return 0; }
#include <iostream>

using namespace std;

// 가로, 세로의 길이는 최대치가 500
constexpr auto MAX = 500;

// 0 빈공간, 1 블록
int map[MAX][MAX];

// 가로 / 세로
int H, W, tempOne, tempTwo;

// 빗물의 개수
int rainwaterCnt = 0;

bool debugbool = true;

// 시각적인 디버깅을 위한 함수
void VisualDebug()
{
	cout << "\n";
	for (int i = 0; i < W; i++)
	{
		for (int j = 0; j < H; j++)
		{
			cout << map[i][j] << " ";
		}
		cout << "\n";
	}
}

// 문제의 입력을 받는 함수
void ReceiveInput()
{
	cin >> H >> W;

	tempTwo = W;

	for (int i = 0; i < tempTwo; i++)
	{
		cin >> tempOne;
		for (int j = 0; j < tempOne; j++)
		{
			map[i][j] = 1;
		}
	}
	
}

// 초기화를 진행하는 함수
void Initialization()
{
	for (int i = 0; i < MAX; i++)
	{
		for (int j = 0; j < MAX; j++)
		{
			map[i][j] = 0;
		}
	}
}

int main()
{
	Initialization();
	ReceiveInput();
	if (debugbool) { VisualDebug(); }

	return 0;
}

문제의 힌트와 배열이 다른 것에 주의

통과된 코드

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <iostream>
using namespace std;
// 가로, 세로의 길이는 최대치가 500
constexpr auto MAX = 500;
// 0 빈공간, 1 블록
int map[MAX][MAX];
// 가로 / 세로
int H, W, tempOne;
// 첫 블록을 마킹하는 bool 값
bool leftRight;
// 빗물의 개수
int rainwaterCnt;
bool debugbool = false;
// 시각적인 디버깅을 위한 함수
void VisualDebug()
{
cout << "\n";
for (int i = 0; i < W; i++)
{
for (int j = 0; j < 10; j++)
{
cout << map[i][j] << " ";
}
cout << "\n";
}
}
// 문제의 입력을 받는 함수
void ReceiveInput()
{
cin >> H >> W;
for (int i = 0; i < W; i++)
{
cin >> tempOne;
for (int j = 0; j < tempOne; j++)
{
map[i][j] = 1;
}
}
}
// 초기화를 진행하는 함수
void Initialization()
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
map[i][j] = 0;
}
}
}
// 빗물을 카운트 합니다.
void CountRainwater()
{
rainwaterCnt = 0;
// 아래부터 위로 검색
for (int i = 0; i < H; i++)
{
leftRight = false;
tempOne = 0;
for (int j = 0; j < W; j++)
{
if (map[j][i] == 1)
{
if (!leftRight)
{
// 좌에서 우로 검색하다 처음 블록을 찾으면 마킹
leftRight = true;
tempOne = 0;
}
else
{
// 마킹이 되어있는 상태에서 블록을 찾으면
// 빈공간을 카운트하는 tempOne을 결과값에 더해준다.
// 그리고 0으로 초기화
rainwaterCnt += tempOne;
tempOne = 0;
}
}
else if (map[j][i] == 0)
{
// 해당 위치가 빈공간이고 첫 블록 마킹이 되어있다면
// 빈공간을 카운트하는 tempOne을 하나 늘려줍니다.
if (leftRight)
{
tempOne++;
}
}
}
}
}
int main()
{
Initialization();
ReceiveInput();
CountRainwater();
if (debugbool) { VisualDebug(); }
// 결과를 출력합니다.
cout << rainwaterCnt;
return 0;
}
#include <iostream> using namespace std; // 가로, 세로의 길이는 최대치가 500 constexpr auto MAX = 500; // 0 빈공간, 1 블록 int map[MAX][MAX]; // 가로 / 세로 int H, W, tempOne; // 첫 블록을 마킹하는 bool 값 bool leftRight; // 빗물의 개수 int rainwaterCnt; bool debugbool = false; // 시각적인 디버깅을 위한 함수 void VisualDebug() { cout << "\n"; for (int i = 0; i < W; i++) { for (int j = 0; j < 10; j++) { cout << map[i][j] << " "; } cout << "\n"; } } // 문제의 입력을 받는 함수 void ReceiveInput() { cin >> H >> W; for (int i = 0; i < W; i++) { cin >> tempOne; for (int j = 0; j < tempOne; j++) { map[i][j] = 1; } } } // 초기화를 진행하는 함수 void Initialization() { for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { map[i][j] = 0; } } } // 빗물을 카운트 합니다. void CountRainwater() { rainwaterCnt = 0; // 아래부터 위로 검색 for (int i = 0; i < H; i++) { leftRight = false; tempOne = 0; for (int j = 0; j < W; j++) { if (map[j][i] == 1) { if (!leftRight) { // 좌에서 우로 검색하다 처음 블록을 찾으면 마킹 leftRight = true; tempOne = 0; } else { // 마킹이 되어있는 상태에서 블록을 찾으면 // 빈공간을 카운트하는 tempOne을 결과값에 더해준다. // 그리고 0으로 초기화 rainwaterCnt += tempOne; tempOne = 0; } } else if (map[j][i] == 0) { // 해당 위치가 빈공간이고 첫 블록 마킹이 되어있다면 // 빈공간을 카운트하는 tempOne을 하나 늘려줍니다. if (leftRight) { tempOne++; } } } } } int main() { Initialization(); ReceiveInput(); CountRainwater(); if (debugbool) { VisualDebug(); } // 결과를 출력합니다. cout << rainwaterCnt; return 0; }
#include <iostream>

using namespace std;

// 가로, 세로의 길이는 최대치가 500
constexpr auto MAX = 500;

// 0 빈공간, 1 블록
int map[MAX][MAX];

// 가로 / 세로
int H, W, tempOne;

// 첫 블록을 마킹하는 bool 값
bool leftRight;

// 빗물의 개수
int rainwaterCnt;

bool debugbool = false;

// 시각적인 디버깅을 위한 함수
void VisualDebug()
{
	cout << "\n";
	for (int i = 0; i < W; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			cout << map[i][j] << " ";
		}
		cout << "\n";
	}
}

// 문제의 입력을 받는 함수
void ReceiveInput()
{
	cin >> H >> W;

	for (int i = 0; i < W; i++)
	{
		cin >> tempOne;
		for (int j = 0; j < tempOne; j++)
		{
			map[i][j] = 1;
		}
	}
}

// 초기화를 진행하는 함수
void Initialization()
{
	for (int i = 0; i < MAX; i++)
	{
		for (int j = 0; j < MAX; j++)
		{
			map[i][j] = 0;
		}
	}
}

// 빗물을 카운트 합니다.
void CountRainwater()
{
	rainwaterCnt = 0;

	// 아래부터 위로 검색
	for (int i = 0; i < H; i++)
	{
		leftRight = false;
		tempOne = 0;

		for (int j = 0; j < W; j++)
		{
			if (map[j][i] == 1)
			{
				if (!leftRight)
				{
					// 좌에서 우로 검색하다 처음 블록을 찾으면 마킹
					leftRight = true;
					tempOne = 0;
				}
				else
				{
					// 마킹이 되어있는 상태에서 블록을 찾으면 
					// 빈공간을 카운트하는 tempOne을 결과값에 더해준다.
					// 그리고 0으로 초기화
					rainwaterCnt += tempOne;
					tempOne = 0;
				}

			}
			else if (map[j][i] == 0)
			{
				// 해당 위치가 빈공간이고 첫 블록 마킹이 되어있다면 
				// 빈공간을 카운트하는 tempOne을 하나 늘려줍니다.
				if (leftRight)
				{
					tempOne++;
				}

			}
		}
	}
}

int main()
{
	Initialization();
	ReceiveInput();
	CountRainwater();
	if (debugbool) { VisualDebug(); }
	// 결과를 출력합니다.
	cout << rainwaterCnt;
	return 0;
}

처음에 생각한 간단한 로직으로 코드를 구현하고 통과한 문제입니다.

이 문제를 해결하는 방법은 다양할 것 같습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다