Skip to content

Conversation

@wnsmir
Copy link
Collaborator

@wnsmir wnsmir commented Aug 21, 2025

๐Ÿ”— ๋ฌธ์ œ ๋งํฌ

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

โœ”๏ธ ์†Œ์š”๋œ ์‹œ๊ฐ„

25min

โœจ ์ˆ˜๋„ ์ฝ”๋“œ

์˜ค๋žœ๋งŒ์— ์‰ฌ์šด ๊ตฌํ˜„๋ฌธ์ œ ๋“ค๊ณ ์™”์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์˜ ํ•ต์‹ฌ์€ ๋ถ™์–ด์žˆ๋Š” ๊ตญ๊ฐ€๋“ค์˜ ๊ตญ๊ฒฝ์„ ์—ฌ๋Š”๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•  ๊ฒƒ์ธ๊ฐ€ ์ž…๋‹ˆ๋‹ค.
์ €๋Š” ์ œ์ผ์ฒ˜์Œ ๋– ์˜ฌ๋ฆฐ๊ฒŒ bfs์˜€์Šต๋‹ˆ๋‹ค. ์ƒํ•˜์ขŒ์šฐ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š”๋ฐ ๊ทธ๋งŒํ•œ๊ฒŒ ์—†๊ธฐ ๋–„๋ฌธ์ด์ฃ .

๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ์กด BFS์˜ ๊ทธ๋ฆฌ๋“œ๋ฒ”์œ„์™€ visited์กฐ๊ฑด ์ด์™ธ์— ์ฐจ์ด์˜ ์ ˆ๋Œ€๊ฐ’์ด R๊ณผ L์‚ฌ์ด์˜ ๊ฐ’ ์•ˆ์— ๋“ค์–ด์˜ค๋Š”๊ฒƒ๋งŒ queue์— appendํ•˜๊ณ  visited์— ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ดํ›„ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ํ•ด๋‹น ๋ฐ˜๋ณตํ„ด์— BFS๋ฉ์–ด๋ฆฌ์— ๋“ค์–ด๊ฐ€๋Š” ๋ชจ๋“  ์ขŒํ‘œ๋“ค์„ ๋”ฐ๋กœ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ํ•ด๋‹น ํ„ด์ด ๋๋‚ ๋•Œ ๊ทธ ๋ธ”๋ก๋“ค์˜ ํ‰๊ท ๊ฐ’์œผ๋กœ
land(์›๋ž˜ ์ขŒํ‘œ)๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์ฃผ๊ณ  ๋‹ค์Œํ„ด์œผ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

๋งคํ„ด i, j ๋ฅผ ๋ชจ๋‘ bfs๋ฅผ ๋Œ๊ฒŒ ์‹œ์ผฐ๋”๋‹ˆ 80%์— ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋‚˜์„œ ๋ฐ˜๋ณต๋ฌธ ์‹œ์ž‘์— visited[i][j]๊ฐ€ True๋ฉด continue๋˜๋„๋ก ๋ฐ”๊ฟ” ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋žœ๋งŒ์— ์†ํ’€๊ณ  ๊ฐ€์‹ญ์‹œ์š”!

from collections import deque

N, L, R = map(int, input().split())

# ์ง€๋„ ๋ฐ›๊ธฐ
land = [list(map(int, input().split())) for _ in range(N)]
move = False
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
day = 0

while True:
    day += 1
    unify = []
    visited = [[False]*N for _ in range(N)]

    for i in range(N):
        for j in range(N):
            # ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ๊ณณ์ด๋ผ๋ฉด pass
            if visited[i][j] == True:
                continue

            start = (i, j)
            queue = deque()
            queue.append(start)
            uni = []
            while queue:
                x, y = queue.popleft()
                for d in range(4):
                    nx = x + dx[d]
                    ny = y + dy[d]
                    if 0 <= nx < N and 0 <= ny < N:
                        if visited[nx][ny] == False:
                            # ์ฐจ์ด๊ฐ€ L์ด์ƒ R์ดํ•˜๋ผ๋ฉด ์ถ”๊ฐ€
                            if L <= abs(land[x][y] - land[nx][ny]) <= R:
                                visited[nx][ny] = True
                                queue.append((nx, ny))
                                uni.append((nx, ny))

            # ์ด๋ฒˆํ„ด์— ์ƒ๊ธด ๋ฉ์–ด๋ฆฌ๋“ค ์ถ”๊ฐ€
            if len(uni) > 0:
                unify.append(uni)
    
    # ์ธ๊ตฌ์ด๋™์ด ์ง„ํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์ธ๊ตฌ์ด๋™ ์ง„ํ–‰
    if len(unify) > 0:
        # ์ธ๊ตฌ์ด๋™ ์ง„ํ–‰
        for uni in unify:
            e_value = 0
            for x, y in uni:
                value = land[x][y] 
                e_value += value
            
            e_count = len(uni)
            population = e_value//e_count
            for u in uni:
                x, y = u
                land[x][y] = population

    # ์•ˆ๋˜๋Š” ๊ฒฝ์šฐ while๋ฌธ ์ข…๋ฃŒํ•˜๊ณ  ํ•ด๋‹น ์ผ์ž print
    else:
        print(day - 1)
        break

Copy link
Collaborator

@kokeunho kokeunho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์˜ˆ์ „์— ํ’€์—ˆ๋˜ ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ตฌํ˜„์€ ์ƒˆ๋กœ ํ•ด๋ณด์ง„ ์•Š์•˜์Šต๋‹ˆ๋‹ค ใ…Žใ…Ž;
์ œ ์˜ˆ์ „ ํ’€์ด๋ฅผ ๋ณด๊ธฐ ์ „์— ์–ด๋–ป๊ฒŒ ํ’€์ง€ ์ƒ๊ฐํ•ด๋ดค๋Š”๋ฐ์š”.
ํ’€์ด๋ฒ•์€ ์ œ๋Œ€๋กœ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

N * N ๋งต์— ์ „์ฒด์—์„œ ๋ชจ๋“  ์นธ์„ ๋ฐฉ๋ฌธํ•  ๋•Œ๊นŒ์ง€ bfs๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  ์นธ์„ ๋ฐฉ๋ฌธํ–ˆ๋‹ค๋ฉด day count๋ฅผ +1 ํ•ด์ค๋‹ˆ๋‹ค.

bfs๋ฅผ ํ•ด์„œ๋Š” ํ˜„์žฌ ์นธ ์‚ฌ๋ฐฉ์œผ๋กœ ์—ฐํ•ฉ์ด ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ 
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด bfs ํ์™€ ์—ฐํ•ฉ์˜ ์ขŒํ‘œ ์ •๋ณด๋ฅผ ๋‹ด๋Š” union ๋ฆฌ์ŠคํŠธ์— ์ขŒํ‘œ๋ฅผ ๋„ฃ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์—ฐํ•ฉ์˜ size๊ฐ€ 1์ด๋ผ๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  1๋ณด๋‹ค ํฌ๋‹ค๋ฉด ์—ฐํ•ฉ์˜ ์ด ์ธ๊ตฌ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋ฐ˜ํ™˜ ๋ฐ›์€ ์ด ์ธ๊ตฌ์ˆ˜๊ฐ€ 0๋ณด๋‹ค ํฌ๋‹ค๋ฉด ์—ฐํ•ฉ์˜ size๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ์—ฐํ•ฉ์— ๋ถ„๋ฐฐํ•ฉ๋‹ˆ๋‹ค.
0์ด๋ผ๋ฉด ์ธ๊ตฌ ์ด๋™์„ ๋ฉˆ์ถ”๊ณ  day count๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

ํ•œ ๋ฒˆ ํ‘ผ ๋ฌธ์ œ๋ฅผ ๋Œ์•„๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋•๋ถ„์— ์ œ ์˜›๋‚  ์ฝ”๋“œ๋„ ๋‹ค์‹œ ๋˜๋Œ์•„๋ณผ ์ˆ˜ ์žˆ์—ˆ๋„ค์š”.
์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค!

Details

import java.sql.SQLOutput;
import java.util.*;

public class Main {

    static int N, R, L;
    static int[][] map;
    static boolean[][] visited;
    static int[][] direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        N = sc.nextInt();
        L = sc.nextInt();
        R = sc.nextInt();

        map = new int[N][N];

        for(int i = 0; i < N; i++) {
            for(int j = 0; j < N; j++) {
                map[i][j] = sc.nextInt();
            }
        }

        int day_count = 0;

        while(true) {
            visited = new boolean[N][N];
            boolean moved = false;

            for(int i = 0; i < N; i++) {
                for(int j = 0; j < N; j++) {
                    if(!visited[i][j]) {
                        List<int[]> union = new ArrayList<> ();
                        int populationSum = bfs(i, j, union);
                        if(populationSum > 0) {
                            moved = true;
                            int newPopulation = populationSum / union.size();
                            for(int[] country : union) {
                                map[country[0]][country[1]] = newPopulation;
                            }
                        }
                    }
                }
            }
            if(!moved) {
                break;
            }
            day_count++;
        }

        System.out.println(day_count);
    }

    private static int bfs(int x, int y, List<int[]> union) {
        Queue<int[]> queue = new LinkedList<> ();
        queue.add(new int[]{x, y});
        union.add(new int[]{x, y});
        visited[x][y] = true;
        int populationSum = map[x][y];

        while(!queue.isEmpty()) {
            int[] now_position = queue.poll();
            int nowX = now_position[0];
            int nowY = now_position[1];

            for(int[] dir : direction) {
                int nx = nowX + dir[0];
                int ny = nowY + dir[1];

                if(nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {
                    int diff = Math.abs(map[nowX][nowY] - map[nx][ny]);
                    if(diff >= L && diff <= R) {
                        visited[nx][ny] = true;
                        queue.add(new int[]{nx, ny});
                        union.add(new int[]{nx, ny});
                        populationSum += map[nx][ny];
                    }
                }
            }
        }
        return union.size() > 1 ? populationSum : 0;
    }
}

Copy link
Collaborator

@kangrae-jo kangrae-jo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ €๋„ ๋ณด๋‹ˆ๊นŒ 9๋‹ฌ์ „์— ํ’€์—ˆ๋˜ ๋ฌธ์ œ๋ผ๊ณ  ๋œจ๋”๋ผ๊ตฌ์š”.
์˜ค๋žœ๋งŒ์— ๋‹ค์‹œ ํ’€์–ด๋ณด๋‹ˆ๊นŒ ์ €๋„ 20๋ถ„-25๋ถ„ ์ •๋„ ๊ฑธ๋ฆฌ๋„ค์š”.
๋ง‰ํž˜์—†์ด ํƒ€์ดํ•‘๋งŒ ํ•œ ๊ฒƒ ๊ฐ™์€๋ฐ... ์‹œ๊ฐ„์ด ๊ฝค๋‚˜ ํ๋ฅด๋„ค์š”.

๊ทธ๋ฆฌ๊ณ  ์˜ˆ์ „์—” ์•„๋งˆ gpt๋ฅผ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์€๋ฐ... ์ด์ œ 20๋ถ„๋Œ€ ์ปท ๋‚ผ์ˆ˜์žˆ์–ด์„œ ๊ธฐ๋ถ„์ด ์ข‹์Šต๋‹ˆ๋‹ค.
๊ณจ๋“œ 4์ง€๋งŒ ๋ง์ด์ฃ  ใ…Žใ…Ž

์ข‹์€ ๋ฌธ์ œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

#include <iostream>
#include <queue>
#include <vector>
#include <cmath>

using namespace std;

const int OFFSET[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

vector<vector<int>> board;
int N, L, R;

bool isIn(int y, int x) { return 0 <= y && y < N && 0 <= x && x < N; }

bool canOpen(int a, int b) {
    int diff = abs(a - b);
    return L <= diff && diff <= R;
}

bool move(vector<vector<bool>>& visited, int sY, int sX) {
    queue<pair<int, int>> q;
    q.push({sY, sX});
    visited[sY][sX] = true;

    queue<pair<int, int>> temp;
    int people = 0;
    bool isMoved = false;

    while (!q.empty()) {
        auto [y, x] = q.front();
        q.pop();

        people += board[y][x];
        temp.push({y, x});

        for (int dir = 0; dir < 4; dir++) {
            int y_ = y + OFFSET[dir][0];
            int x_ = x + OFFSET[dir][1];
            if (isIn(y_, x_) && !visited[y_][x_] && canOpen(board[y][x], board[y_][x_])) {
                q.push({y_, x_});
                visited[y_][x_] = true;
                isMoved = true;
            }
        }
    }

    int moved = people / temp.size();
    while (!temp.empty()) {
        auto [y, x] = temp.front();
        temp.pop();

        board[y][x] = moved;
    }

    return isMoved;
}

int main() {
    cin >> N >> L >> R;

    board = vector<vector<int>>(N, vector<int>(N, 0));
    for (int y = 0; y < N; y++) {
        for (int x = 0; x < N; x++) {
            cin >> board[y][x];
        }
    }

    int answer = 0;
    while (true) {
        bool isMoved = false;
        vector<vector<bool>> visited(N, vector<bool>(N, false));
        for (int y = 0; y < N; y++) {
            for (int x = 0; x < N; x++) {
                if (!visited[y][x] && move(visited, y, x)) {
                    isMoved = true;
                }
            }
        }
        if (!isMoved) break;
        else answer ++;
    }

    cout << answer << '\n';

    return 0;
}

Copy link
Member

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2๋…„ ์ „์— ์ฒ˜์Œ ํ’€์—ˆ์„ ๋•Œ 556ms๋กœ ํ†ต๊ณผํ–ˆ์—ˆ๋Š”๋ฐ, 3๋‹ฌ ์ „์— ๋‹ค์‹œ ํ’€์—ˆ์„ ๋•Œ 20ms๋กœ ํ†ต๊ณผํ–ˆ๋„ค์š”(์–ด์ผ€ ํ–ˆ์ง€?)...

๊ธฐ์–ต์ด ์•ˆ๋‚˜์„œ ์ฝ”๋“œ๋งŒ ๋˜์ ธ๋ด…๋‹ˆ๋‹ค ํ—ˆํ—ˆ

์ฐธ๊ณ ๋กœ ์š”๊ฑฐ ๋„ค์ด๋ฒ„ ๊ธฐ์ถœ๋กœ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฑฐ์˜ ํ•„์ˆ˜ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜์ฃ  :)

#include <iostream>
#include <vector>
#include <queue>

using namespace std;
using FVector2 = pair<int, int>;

const vector<FVector2> Offset
{
    {-1, 0},
    {0, 1},
    {1, 0},
    {0, -1},
};

int N, L, R;
vector<vector<int>> A;
vector<vector<bool>> Visited;
queue<FVector2> PositionQ;

bool OutOfBound(int x, int y)
{
    return x < 0 || x >= N || y < 0 || y >= N;
}

bool ShouldOpenBorderBetween(int x, int y, int nx, int ny)
{
    int PopulationDifferences = abs(A[x][y] - A[nx][ny]);
    if(L <= PopulationDifferences && PopulationDifferences <= R)
    {
        return true;
    }
    
    return false;
}

bool BFS(int StartX, int StartY)
{
    Visited[StartX][StartY] = true;
    
    queue<FVector2> Q;
    Q.emplace(StartX, StartY);
    
    vector<FVector2> OpenedCells;
    int SumPopulation = 0;
    
    bool bOpenBorder = false;
    while(!Q.empty())
    {
        const auto [x, y] = Q.front(); Q.pop();
        OpenedCells.emplace_back(x, y);
        SumPopulation += A[x][y];
        
        for(const auto& [dx, dy] : Offset)
        {
            int nx = x + dx, ny = y + dy;
            if(OutOfBound(nx, ny) || Visited[nx][ny])
            {
                continue;
            }
            
            if(ShouldOpenBorderBetween(x, y, nx, ny))
            {
                Visited[nx][ny] = true;
                Q.emplace(nx, ny);
                bOpenBorder = true;
            }
        }
    }
    
    if(!bOpenBorder)
    {
        return false;
    }
    
    int Population = SumPopulation / OpenedCells.size();
    for(const auto& [x, y] : OpenedCells)
    {
        A[x][y] = Population;
        PositionQ.emplace(x, y);
    }
    
    return true;
}

bool ShouldMigration(int x, int y)
{
    for(const auto& [dx, dy] : Offset)
    {
        int nx = x + dx, ny = y + dy;
        if(OutOfBound(nx, ny))
        {
            continue;
        }
        
        if(ShouldOpenBorderBetween(x, y, nx, ny))
        {
            return true;
        }
    }
    
    return false;
}

int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    
    cin >> N >> L >> R;
    A.resize(N, vector<int>(N));
    
    for(int i = 0; i < N; ++i)
    {
        for(int j = 0; j < N; ++j)
        {
            cin >> A[i][j];
            PositionQ.emplace(i, j);
        }
    }
    
    int Day = 0;
    while(true)
    {
        Visited.assign(N, vector<bool>(N, false));
        bool bPopulationMoved = false;
        
        for(int Repeat = PositionQ.size(); Repeat > 0; --Repeat)
        {
            const auto [x, y] = PositionQ.front(); PositionQ.pop();
            if(Visited[x][y] || !ShouldMigration(x, y))
            {
                continue;
            }
            
            if(BFS(x, y))
            {
                bPopulationMoved = true;
            }
        }
        
        if(!bPopulationMoved)
        {
            break;
        }
        
        ++Day;
    }
    
    cout << Day;

    return 0;
}

Copy link
Collaborator

@g0rnn g0rnn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ €๋„ ์˜ˆ์ „์— ํ’€์—ˆ๋˜ ๋ฌธ์ œ์ธ๋ฐ ์ด๋ฒˆ์—” ์ข€ ์˜ค๋ž˜ ๊ฑธ๋ ธ๋„ค์š”. ๊ณผ์ •์„ ๋˜๋Œ์•„๋ณด๋ฉด ๋งจ ์ฒ˜์Œ ์„ค๊ณ„ํ•  ๋•Œ ์ธ๊ตฌ๊ฐ€ ์ด๋™๋๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ๋œ๊ฑฐ ๊ฐ™์Šด๋‹ค..

bfs๋กœ ์—ฐํ•ฉ์„ ๊ตฌ์„ฑํ•˜๊ณ  flatten์œผ๋กœ ์ธ๊ตฌ ์ˆ˜๋ฅผ ๋งž์ถฅ๋‹ˆ๋‹ค. flatten์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์ด์ „๊ณผ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์ˆ˜์ •๋˜๋Š” ๊ฒฝ์šฐ ์ธ๊ตฌ ์ด๋™์œผ๋กœ ๊ฐ์ง€ํ•˜๊ณ  moved ํ”Œ๋ž˜๊ทธ๋ฅผ ๋ณ€๊ฒฝ์‹œ์ผœ ์ธ๊ตฌ ์ด๋™ ์ข…๋ฃŒ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ข€ ๋” ์ง‘์ค‘ํ•ด์„œ ํ’€์—ˆ๋‹ค๋ฉด ๊ธˆ๋ฐฉ ํ’€์—ˆ์„๊ฒƒ ๊ฐ™๋„ค์š” ์ข‹์€ ๋ฌธ์ œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹น

package beakjoon;

import java.io.*;
import java.util.*;

public class Sol16234 {

    static int n, l, r;
    static int[][] city;
    static int[][] offset = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        l = Integer.parseInt(st.nextToken());
        r = Integer.parseInt(st.nextToken());

        city = new int[n][n];
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                city[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int answer = 0;
        boolean[][] visited;
        while (true) {
            // ๋ชจ๋“  ๋„์‹œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ
                // ์—ฐ๊ฒฐ๊ฐ€๋Šฅํ•˜๋ฉด ์—ฐ๊ฒฐํ•˜๊ณ 
                // ์ธ๊ตฌ ์ด๋™
            visited = new boolean[n][n];
            boolean isMoved = false;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (visited[i][j]) continue;
                    List<int[]> part = bfs(j, i, visited, city);
                    isMoved = isMoved | flatten(city, part);
                }
            }
            if (!isMoved) {
                break;
            }
            answer++;
        }
        System.out.println(answer);
        br.close();
    }

    private static List<int[]> bfs(int x, int y, boolean[][] visited, int[][] city) {
        List<int[]> result = new ArrayList<>();
        Queue<int[]> q = new ArrayDeque<>();
        q.add(new int[]{x, y});
        result.add(new int[]{x, y});
        visited[y][x] = true;

        while (!q.isEmpty()) {
            int cx = q.peek()[0];
            int cy = q.poll()[1];

            for (int[] o : offset) {
                int nx = cx + o[0];
                int ny = cy + o[1];

                if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
                if (visited[ny][nx]) continue;
                int diff = Math.abs(city[cy][cx] - city[ny][nx]);
                if (!(l <= diff && diff <= r)) continue;
                q.add(new int[]{nx, ny});
                result.add(new int[]{nx, ny});
                visited[ny][nx] = true;
            }
        }
        return result;
    }

    private static boolean flatten(int[][] city, List<int[]> part) {
        boolean moved = false;
        int size = part.size();
        if (size == 1) return moved;

        int sum = 0;
        for (int i = 0; i < size; i++) {
            int x = part.get(i)[0];
            int y = part.get(i)[1];
            sum += city[y][x];
        }
        final int avg = sum / size;
        for (int[] p : part) {
            if (city[p[1]][p[0]] != avg) moved = true;
            city[p[1]][p[0]] = avg;
        }
        return moved;
    }
}

@g0rnn g0rnn merged commit 154d10b into main Sep 4, 2025
1 check passed
@g0rnn g0rnn deleted the 33-wnsmir branch September 4, 2025 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants