알고리즘
89. 토마토 [BFS]
홍루피
2021. 3. 22. 16:26
인프런 - it 취업을 위한 알고리즘 문제풀이 (with C/C++) : 코딩테스트 대비 강의를 바탕으로 공부한 내용입니다.
풀이
- 토마토가 다 익는 날짜를 출력하는 문제
- tom 배열에 입력을 받고 1일때마다 큐에 넣는다. (큐에는 Loc 형이 들어가서 (x, y)형태로 저장이 된다.)
- 상하좌우 탐색 하는데 새로구한 좌표에 들어있는 값이 0일때만 경계 안에 있는지 확인 후 큐에 넣어준다.
- 큐에 넣은 후 해당 배열의 값을 1로 만들고(check)
- dis배열(해당 좌표의 토마토가 익는 날짜수를 갖고 있음)의 카운트를 dis[tmp.x][tmp.y]에 들어있는 값+1로 한다.
- 플래그 f를 사용해 tom배열에서 0이 있는지 검사 => 0이 남아있으면 f=0으로 변경 => -1출력
- f=1이면 모든 토마토가 익었다는 의미 => dis의 최대값을 찾아 res에 넣어준다.
** 이때 초기상태가 모두 익은 토마토라면 dis는 0인 상태로 남아있을 것이고 res는 0이다.(별도 처리 필요 없음)
헷갈리는 포인트 정리
1) 뻗어나갈 시작 좌표를 찾는 것
=> 기존 BFS문제에서는 0, 0이라는 시작점이 주어졌다.
=> 해당 문제는 입력 시 1이 들어올때마다 큐에 넣어 시작점을 직접 만들어 줘야 한다.
2) dis배열의 사용
=> 자신이 뻗어나온 곳의 dis배열에 +1한 값이 거리가 된다
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
int m, n, tom[1010][1010], res = -2147000000, dis[1010][1010];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
struct Loc
{
int x;
int y;
Loc(int a, int b)
{
x = a;
y = b;
}
};
queue<Loc> Q;
int main()
{
int i, j;
scanf("%d %d", &m, &n); //m열 n행
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
scanf("%d", &tom[i][j]);
if (tom[i][j] == 1)
Q.push(Loc(i, j));
}
}
while (!Q.empty())
{
Loc tmp = Q.front();
Q.pop();
for (i = 0; i < 4; i++)
{
int xx = tmp.x + dx[i];
int yy = tmp.y + dy[i];
if (tom[xx][yy] == 0)
{
if (xx >= 1 && xx <= n && yy >= 1 && yy <= m)
{
Q.push(Loc(xx, yy));
tom[xx][yy] = 1;
dis[xx][yy] = dis[tmp.x][tmp.y] + 1;
}
}
}
}
int f = 1;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
if (tom[i][j] == 0)
f = 0;
}
}
if (f == 1)
{
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
if (res < dis[i][j])
res = dis[i][j];
}
}
printf("%d\n", res);
}
else
printf("-1");
return 0;
}