문제 링크
풀이
DFS
로 풀긴 했는데, BFS
가 편했을 것 같다..
- 값을 입력 받으며 벡터를 만든다.
- 인구 이동이 있어 다시 확인해야 하는지 체크하기 위한 변수
flag
가true
라면 계속 인구 이동 시킨다. 첫번째는 인구 이동을 해야하는지 체크해야 하므로do-while
문을 쓴다. - 벡터를 돌며
visited[i][j]
가0
이면 탐색되지 않았다는 것이므로dfs
함수로 탐색을 시작한다.dfs
함수에서는 상하좌우를 확인하며gap
이 범위 안에 있다면 재귀 호출을 한다.- 영역 내의 총 합을 구하기 위한
sum
과 영역 칸의 개수를 구하기 위한cnt
를 갱신한다. - 영역 구분이 끝나면
arr
의 값을 바꿔줘야 하므로 해당 위치 값을 갖는unionArr
에 추가한다.
dfs
를 돌고 한 영역이라도1
보다 크다면(연합을 맺었다면) 인구 이동을 다시 체크해야 한다.flag
를true
로 하고,arr
의 값을 바꿔준다.flag
가true
일 때는 인구 이동을 위해 계속해서days++
해준다.days
를 출력하면 끝
코드
#include <iostream>
#include <vector>
using namespace std;
int dy[4] = { -1,0,1,0 };
int dx[4] = { 0,1,0,-1 };
int n, l, r;
int cnt = 0;
int sum = 0;
vector<pair<int, int>> unionArr;
void dfs(int y, int x, vector<vector<int>> &visited, vector<vector<int>> &arr)
{
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 >= n) continue;
if (visited[ny][nx]) continue;
int gap = abs(arr[ny][nx] - arr[y][x]);
if (gap >= l && gap <= r)
{
visited[ny][nx] = 1;
dfs(ny, nx, visited, arr);
}
}
sum += arr[y][x];
cnt++;
unionArr.push_back({ y,x });
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> l >> r;
vector<vector<int>> arr(n, vector<int>(n));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> arr[i][j];
}
}
vector<vector<int>> visited(n, vector<int>(n));
bool flag = false; // 인구 이동이 있어 다시 체크해야 함
int days = 0;
do
{
visited.clear();
visited.resize(n, vector<int>(n));
flag = false;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (visited[i][j] == 0)
{
sum = 0;
cnt = 0;
unionArr.clear();
visited[i][j] = 1;
dfs(i, j, visited, arr);
if (cnt > 1)
{
flag = true;
}
for (auto u : unionArr)
{
arr[u.first][u.second] = sum / cnt;
}
}
}
}
if (flag) days++;
} while (flag);
cout << days;
}