My Profile

김형훈

안녕하세요.
김형훈입니다.

백준 2636 치즈

백준 2636 치즈

2022년 11월 27일

2022년 11월 27일

cpp, 탐색

문제

문제

풀이

풀이

해당 문제의 풀이는 다음과 같다.

  1. 탐색을 통해 치즈의 가장자리에 해당하는 칸을 찾는다.

  2. 치즈의 가장자리를 빈 공간으로 표시해준다.

이때 치즈의 가장자리는 공기와 접촉된 공간으로, 치즈 내부의 구멍과 구분되어야 한다. 공기는 판의 가장자리와 닿는 공간으로 표시할 수 있고, 판의 가장자리에는 항상 치즈가 오지 않는다고 명시되있기 때문에 0,0번째 칸부터 비어있는 칸을 탐색하면 구멍이 아닌 공간을 탐색할 수 있다.
비어있는 칸을 탐색하며 치즈에 해당하는 칸을 찾을 경우, 해당 칸을 치즈의 가장자리로 표시해주면 된다.

코드

코드

#include <bits/stdc++.h>

using namespace std;

int r, c, days, ans;
int board[102][102];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};

bool find_edge()
{
	// 바깥부분을 탐색하다가 치즈를 만나면, 해당 치즈가 가장자리임을 알 수 있다.
	bool vis[102][102] = {0,};
	queue<pair<int, int>> q;
	vis[0][0] = true;
	q.push({0, 0}); // 판의 가장자리는 치즈가 놓이지 않는다고 제시되어서 0,0부터 탐색
	bool cheese_remain = false;
	while (!q.empty())
	{
		auto cur = q.front();
		q.pop();
		for (int dir = 0; dir < 4; ++dir)
		{
			int nx = cur.first + dx[dir];
			int ny = cur.second + dy[dir];
			if (nx < 0 || ny < 0 || nx >= r || ny >= c) continue;
			if (vis[nx][ny]) continue;
			if (board[nx][ny] == 2)
			{
				cheese_remain = true;
				continue;
			}
			if (board[nx][ny] == 1)
			{
				board[nx][ny] = 2;
				cheese_remain = true;
				continue; // 치즈 발견시 표시 후 continue
			}
			vis[nx][ny] = true;
			q.push({nx, ny});
		}
	}
	if (!cheese_remain) return false;
	days++;
	return true;
}

int remove_edge()
{
	bool vis[102][102] = {0,};
	queue<pair<int, int>> q;
	int remain_cheese = 0;
	for (int i = 0; i < r; ++i)
		for (int j = 0; j < c; ++j)
		{
			if (vis[i][j] || !board[i][j]) continue;
			vis[i][j] = true;
			q.push({i, j});
			while (!q.empty())
			{
				auto cur = q.front();
				q.pop();
				remain_cheese++;
				if (board[cur.first][cur.second] == 2)
					board[cur.first][cur.second] = 0; // 가장자리 치즈 제거
				for (int dir = 0; dir < 4; ++dir)
				{
					int nx = cur.first + dx[dir];
					int ny = cur.second + dy[dir];
					if (nx < 0 || ny < 0 || nx >= r || ny >= c) continue;
					if (vis[nx][ny] || !board[nx][ny]) continue;
					vis[nx][ny] = true;
					q.push({nx, ny});
				}
			}
		}
	return remain_cheese;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> r >> c;
	for (int i = 0; i < r; ++i)
		for (int j = 0; j < c; ++j)
			cin >> board[i][j];
	while (find_edge())
		ans = remove_edge();
	cout << days << '\n' << ans;
}

결과

결과

Copyright © 2024 Hyunghoon Kim