#include <iostream>
#include <tuple>
#include <vector>
#include <string.h>
#include <queue>
int DirX[4] = { 1,-1,0,0 };
int DirY[4] = { 0,0,1,-1 };
int graph[301][301] = {};
bool visit[301][301] = {};
int main()
{
int N = 0;
int M = 0;
std::cin >> N >> M;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < M; ++j)
{
std::cin >> graph[i][j];
}
}
std::queue<std::pair<int, int>> que = {};
for (int iCount = 0; ; ++iCount)
{
int iNumber = 0;
bool haveIce = false;
std::queue<std::tuple<int, int, int>> nextQue = {};
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < M; ++j)
{
if (graph[i][j] != 0 && !visit[i][j])
{
haveIce = true;
que.push({ i,j });
visit[i][j] = true;
++iNumber;
if (iNumber >= 2)
{
std::cout << iCount;
return 0;
}
}
while (!que.empty())
{
int iX = que.front().first;
int iY = que.front().second;
que.pop();
int iZero = 0;
for (int z = 0; z < 4; ++z)
{
int iNextX = iX + DirX[z];
int iNextY = iY + DirY[z];
if (iNextX >= 0 && iNextX < N &&
iNextY >= 0 && iNextY < M)
{
if (graph[iNextX][iNextY] && !visit[iNextX][iNextY])
{
que.push({ iNextX,iNextY });
visit[iNextX][iNextY] = true;
}
if (!graph[iNextX][iNextY])
++iZero;
}
}
nextQue.push({ iZero , iX,iY });
}
}
}
if (haveIce)
haveIce = false;
else
{
std::cout << 0;
return 0;
}
iNumber = 0;
while (!nextQue.empty())
{
int iZero = std::get<0>(nextQue.front());
int iX = std::get<1>(nextQue.front());
int iY = std::get<2>(nextQue.front());
nextQue.pop();
graph[iX][iY] = std::max(0, graph[iX][iY] - iZero);
}
memset(visit, false, sizeof(visit));
}
return 0;
}
1. BFS로 검사하면서 나뉜 순간 횟수를 출력
2. 검사하면서 주변이 0인지 확인하고 다음에 지울만큼을 nextQue에 입력
3. 검사를 다 끝내고 다 못했을 경우 nextQue를 낮춰준다.
'오늘의 알고리즘' 카테고리의 다른 글
[C++] 백준 1655 가운데를 말해요 (0) | 2022.05.19 |
---|---|
[C++] 백준 14503 로봇 청소기 (0) | 2022.05.18 |
[C++] 백준 3197 백조의 호수 (0) | 2022.05.14 |
[C++] 백준 12865 평범한 배낭 (0) | 2022.05.14 |
[C++] 백준 2468 안전 영역 (0) | 2022.05.13 |