https://www.acmicpc.net/problem/2638
문제
N×M (5≤N, M≤100)의 모눈종이 위에 아주 얇은 치즈가 <그림 1>과 같이 표시되어 있다. 단, N 은 세로 격자의 수이고, M 은 가로 격자의 수이다. 이 치즈는 냉동 보관을 해야만 하는데 실내온도에 내어놓으면 공기와 접촉하여 천천히 녹는다. 그런데 이러한 모눈종이 모양의 치즈에서 각 치즈 격자(작 은 정사각형 모양)의 4변 중에서 적어도 2변 이상이 실내온도의 공기와 접촉한 것은 정확히 한시간만에 녹아 없어져 버린다. 따라서 아래 <그림 1> 모양과 같은 치즈(회색으로 표시된 부분)라면 C로 표시된 모든 치즈 격자는 한 시간 후에 사라진다.
<그림 1>
<그림 2>와 같이 치즈 내부에 있는 공간은 치즈 외부 공기와 접촉하지 않는 것으로 가정한다. 그러므 로 이 공간에 접촉한 치즈 격자는 녹지 않고 C로 표시된 치즈 격자만 사라진다. 그러나 한 시간 후, 이 공간으로 외부공기가 유입되면 <그림 3>에서와 같이 C로 표시된 치즈 격자들이 사라지게 된다.
<그림 2>
<그림 3>
모눈종이의 맨 가장자리에는 치즈가 놓이지 않는 것으로 가정한다. 입력으로 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 구하는 프로그램을 작성하시오
쉬운 BFS문제이다. 외부 공기와 내부 공기만 분리하면 되는데 맨 가장자리에는 치즈가 놓이지 않는다는 조건이 있기
때문에 맨 가장자리에서 시작해서 갈 수 있는 곳들은 모두 들어가고 치즈를 만나면 그 치즈가 만나는 벽의 개수를 저장시켜주면 된다. 그리고 모든 탐색이 끝나고 저장해놓은 치즈가 만난 벽의 개수를 확인하여 2개 이상인 경우 그 치즈를 녹여주기만 하면 된다.
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <bitset>
#define CUNLINK ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
int N, M;
int board[101][101];
int visited[101][101];
int Cheese[101][101];
const int dy[] = { 1,-1,0,0 };
const int dx[] = { 0,0,1,-1 };
bool isEnd() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (board[i][j] == 1) return false;
}
}
return true;
}
void Melt_Cheese() {
memset(visited, 0, sizeof(visited));
memset(Cheese, 0, sizeof(Cheese));
queue<pair<int, int>> q;
q.push({ 0,0 });
visited[0][0] = 1;
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
if (ny < 0 || ny >= N || nx < 0 || nx >= M) continue;
if (visited[ny][nx]) continue;
if (board[ny][nx] == 0) {
visited[ny][nx] = 1;
q.push({ ny, nx });
}
else if (board[ny][nx] == 1) {
Cheese[ny][nx]++;
}
}
}
}
void go_erase() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (Cheese[i][j] >= 2) {
board[i][j] = 0;
}
}
}
}
int main() {
CUNLINK;
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> board[i][j];
}
}
int Cnt = 0;
while (1) {
if (isEnd()) break;
Melt_Cheese();
go_erase();
Cnt++;
}
cout << Cnt << endl;
return 0;
}
'BOJ > BFS\DFS' 카테고리의 다른 글
[C/C++] 백준 - 14442번 : 벽 부수고 이동하기2 (0) | 2021.08.23 |
---|---|
[C/C++] 백준 - 1963번 : 소수 경로 (0) | 2021.08.21 |
[C/C++] 백준 - 11967번 : 불켜기 (0) | 2021.08.20 |
[C/C++] 백준 - 14940번 : 쉬운 최단거리 (0) | 2021.08.16 |
[C/C++] 백준 - 16954번 : 움직이는 미로 탈출 (0) | 2021.08.15 |