[백준 16234번 C/C++] 인구 이동
[백준 16234번 C/C++] 인구 이동
https://www.acmicpc.net/problem/16234
해결전략
너비 우선 탐색 BFS
코드
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int dy[4] = {-1, 1, 0, 0}; // 선언: 상, 하 이동
const int dx[4] = {0, 0, -1, 1}; // 선언: 좌, 우 이동
int n, l, r; // 선언: n - 격자 크기, l - 최소 인구 차이, r - 최대 인구 차이
int a[50][50]; // 선언: 각 나라의 인구 수 행렬
bool visit[50][50]; // 선언: 각 나라의 방문 여부 행렬
vector<pair<int, int>> open; // 선언: 연합국 위치 저장
// bfs 함수: 인구 이동이 가능한 인접한 나라를 찾는 함수
bool bfs(int y, int x) {
if (visit[y][x]) return false; // 이미 방문한 나라라면 false 반환
open.clear(); // 연합국 위치 저장 벡터 초기화
queue<pair<int, int>> q; // 선언: 연합국 위치 저장 큐
q.push(make_pair(y, x)); // 해당 위치를 큐에 추가
visit[y][x] = true; // 그 위치를 방문 표시
open.push_back(make_pair(y, x)); // 연합국 위치 저장 벡터에 추가
while (!q.empty()) { // 큐가 빌 때까지 반복
int cy = q.front().first;
int cx = q.front().second;
q.pop();
for (int dir = 0; dir < 4; ++dir) { // 상, 하, 좌, 우 방향 범위
int ny = cy + dy[dir]; // 새로운 y 위치 계산
int nx = cx + dx[dir]; // 새로운 x 위치 계산
if (ny < 0 || ny >= n || nx < 0 || nx >= n) continue; // 격자 밖에 있다면 다음 방향 확인
if (visit[ny][nx]) continue; // 이미 방문한 경우 다음 방향 확인
int diff = abs(a[ny][nx] - a[cy][cx]); // 인접한 나라의 인구 차이 계산
if (l <= diff && diff <= r) { // 인구 차이가 l 이상 r 이하일 경우
q.push(make_pair(ny, nx)); // 큐에 위치 저장
visit[ny][nx] = true; // 방문 표시
open.push_back(make_pair(ny, nx)); // 연합국 위치 저장 벡터에 추가
}
}
}
return open.size() > 1; // 연합국이 2개 이상이면 true 반환, 아니면 false 반환
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> l >> r; // 입력: n, l, r
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> a[i][j]; // 입력: 각 나라의 인구 수 행렬 a
}
}
int ans = 0; // 선언 및 초기화: 인구 이동이 발생한 총 라운드 수
while (true) { // 인구 이동이 더 이상 발생하지 않을 때까지 반복
memset(visit, false, sizeof(visit)); // 방문 배열 초기화
bool flag = false; // 선언 및 초기화: 이동 여부 플래그
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (bfs(i, j)) { // 해당 위치에서 bfs 실행 후 연합국이 2개 이상일 경우
flag = true; // 이동 여부 플래그 true로 설정
int sum = 0; // 선언 및 초기화: 연합국 인구 수 총합
for (auto& p : open) {
sum += a[p.first][p.second]; // 연합국 인구 수 누적
}
int avg = sum / open.size(); // 연합국 인구 평균
for (auto& p : open) {
a[p.first][p.second] = avg; // 연합국별로 새로운 인구 수 할당
}
}
}
}
if (!flag) break; // 이동이 발생하지 않은 경우 라운드 종료
ans++; // 인구 이동이 발생한 경우 라운드 수 증가
}
cout << ans << '\n'; // 결과 출력: 인구 이동이 발생한 총 라운드 수
return 0;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 1629번 C/C++] 곱셈 (0) | 2023.07.31 |
---|---|
[백준 13305번 C/C++] 주유소 (0) | 2023.07.28 |
[백준 11404번 C/C++] 플로이드 (0) | 2023.07.25 |
[백준 2293번 C/C++] 동전 1 (0) | 2023.07.24 |
[백준 2447번 C/C++] 별 찍기 (0) | 2023.07.21 |
댓글
이 글 공유하기
다른 글
-
[백준 1629번 C/C++] 곱셈
[백준 1629번 C/C++] 곱셈
2023.07.31 -
[백준 13305번 C/C++] 주유소
[백준 13305번 C/C++] 주유소
2023.07.28 -
[백준 11404번 C/C++] 플로이드
[백준 11404번 C/C++] 플로이드
2023.07.25 -
[백준 2293번 C/C++] 동전 1
[백준 2293번 C/C++] 동전 1
2023.07.24