오늘의 알고리즘

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

하늘하늘 . 2022. 5. 30. 15:43
 
#include <iostream>
#include <string.h>
#include <vector>
#include <iostream>
#include <queue>
#include <tuple>
 
int graph[51][51] = {};
bool visit[51][51] = {};
int iDirX[4] = { 1,-1,0,0 };
int iDirY[4] = { 0,0,1,-1 };
 
int main() 
{
    int N = 0;
    int L = 0;
    int R = 0;
    bool bChange = false;
    int iCount = 0;
 
    std::cin >> N >> L >> R;
 
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            std::cin >> graph[i][j];
        }
    }
 
 
    while (true)
    {
        std::queue<std::pair<int, int>> que = {};
 
        for (int i = 0; i < N; ++i)
        {
            for (int j = 0; j < N; ++j)
            {
                std::vector<std::pair<int, int>> vec = {};
 
                if (!visit[i][j])
                {
                    vec.push_back({ i,j });
                    visit[i][j] = true;
                    que.push({ i,j });
                }
 
                while (!que.empty())
                {
                    int iX = que.front().first;
                    int iY = que.front().second;
                    int iNumber = graph[iX][iY];
                    que.pop();
 
                    for (int z = 0; z < 4; ++z)
                    {
                        int iNextX = iX + iDirX[z];
                        int iNextY = iY + iDirY[z];
 
                        if (iNextX >= 0 && iNextX < N &&
                            iNextY >= 0 && iNextY < N)
                        {
                            if ((graph[iNextX][iNextY] <= iNumber + R && graph[iNextX][iNextY] >= iNumber + L) ||
                                (graph[iNextX][iNextY] >= iNumber - R && graph[iNextX][iNextY] <= iNumber - L))
                            {
                                if (!visit[iNextX][iNextY])
                                {
                                    bChange = true;
                                    visit[iNextX][iNextY] = true;
                                    vec.push_back({ iNextX,iNextY });
                                    que.push({ iNextX,iNextY });
                                }
                            }
                        }
                    }
                }
 
                if (vec.size() > 1)
                {
                    int iSum = 0;
 
                    for (int z = 0; z < vec.size(); ++z)
                    {
                        iSum += graph[vec[z].first][vec[z].second];
                    }
 
                    for (int z = 0; z < vec.size(); ++z)
                    {
                        graph[vec[z].first][vec[z].second] = iSum / vec.size();
                    }
 
                }
            }
        }
 
        if (bChange)
        {
            ++iCount;
            bChange = false;
            memset(visit, false, sizeof(visit));
        }
 
        else
        {
            std::cout << iCount;
            return 0;
        }
    }
}

처음에는 다음 껄 복사해놨다가 해야하나 고민했었는데 하다보니 어짜피 방문한 곳들은 안들어가면 상관없구나 싶어서

1. que로 내부를 확인

2. visit해서 방문하지 않은 곳만 들어가고

3. 다음 while 때 하나도 못한다면 아예 return할 수 있도록