길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm/Simulation

[백준 16234번] 인구 이동 (C/C++)

2022. 3. 25. 06:27

https://www.acmicpc.net/problem/16234

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모

www.acmicpc.net


인구 이동 문제는 BFS를 이용하여 해결했습니다. 

 

각 좌표를 시작점으로 BFS를 수행하여, 인구 차이가 L명 이상, R명 이하인 연합을 찾고, 각 연합에 대해 인구 이동을 시킨 뒤, 다시 BFS를 수행합니다.

BFS를 수행하고 나서 더이상 연합이 존재하지 않는다면, 종료하면 됩니다.

 

전체 코드는 아래와 같습니다.

 

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second

int board[50][50];  // 각국의 인구를 저장하는 배열
int vis[50][50];    // 방문 표시 배열

int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int n, l, r;
    cin >> n >> l >> r;

    for(int i = 0; i < n; i++)  
        for(int j = 0; j < n; j++)
            cin >> board[i][j]; // 인구 입력 받음

    int ans = 0;    // 인구 이동 발생 일수
    while(true){
        vector<vector<pair<int, int>>> as;  // 연합의 좌표
        
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                fill(&vis[0][0], &vis[49][50], 0);

                vector<pair<int, int>> a;   // 연합의 좌표
                queue<pair<int, int>> q;   
                q.push({i, j}); 
                vis[i][j] = 1;

                while(!q.empty()){
                    pair<int, int> cur = q.front(); q.pop();
                    a.push_back(cur);

                    for(int dir = 0; dir < 4; dir++){
                        int nx = cur.x + dx[dir];
                        int ny = cur.y + dy[dir];

                        if(nx < 0 || ny < 0 || nx >= n || ny >= n || vis[nx][ny] != 0) continue;
                        if(abs(board[nx][ny] - board[cur.x][cur.y]) < l
                        || abs(board[nx][ny] - board[cur.x][cur.y]) > r) continue;
                        // 국경선을 공유하는 두 나라의 인구 차이가 L명 이상, R명 이하라면
                        q.push({nx, ny});
                        vis[nx][ny] = 1;
                    }
                }
                if(a.size() > 1) as.push_back(a);   // 국경선을 공유하는 나라가 2 이상이라면
            }
        }
        
        if(as.size() == 0) break;   // 둘 이상의 나라로 구성된 연합이 존재하지 않는다면 인구 이동 종료
        else{    // 둘 이상의 나라로 구성된 연합이 존재한다면
            ans++;
            for(auto p : as){   // 각 연합에 대해 반복
                int t = 0;
                // 연합을 이루고 있는 각 칸의 인구수는 (연합의 인구수) / (연합을 이루고 있는 칸의 개수)
                for(auto na : p) t += board[na.x][na.y];    
                for(auto na : p) board[na.x][na.y] = t/p.size();
            }
        }
    }
    cout << ans;
}

 

'Algorithm > Simulation' 카테고리의 다른 글

[백준 16236번] 아기 상어 (C/C++)  (0) 2022.03.27
[백준 16235번] 나무 재테크 (C/C++)  (0) 2022.03.27
[백준 17281번] ⚾ (C/C++)  (0) 2022.03.25
[백준 5373번] 큐빙 (C/C++)  (0) 2022.03.25
[백준 15685번] 드래곤 커브 (C/C++)  (0) 2022.03.23
    'Algorithm/Simulation' 카테고리의 다른 글
    • [백준 16236번] 아기 상어 (C/C++)
    • [백준 16235번] 나무 재테크 (C/C++)
    • [백준 17281번] ⚾ (C/C++)
    • [백준 5373번] 큐빙 (C/C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바