[Boj_20058] ๋งˆ๋ฒ•์‚ฌ ์ƒ์–ด์™€ ํŒŒ์ด์–ด์Šคํ†ฐ

๐Ÿ“Ž ๋ฌธ์ œ ๋งํฌ

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

 

โ–ธ ๋ฌธ์ œ

๋งˆ๋ฒ•์‚ฌ ์ƒ์–ด๋Š” ํŒŒ์ด์–ด๋ณผ๊ณผ ํ† ๋„ค์ด๋„๋ฅผ ์กฐํ•ฉํ•ด ํŒŒ์ด์–ด์Šคํ†ฐ์„ ์‹œ์ „ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ค๋Š˜์€ ํŒŒ์ด์–ด์Šคํ†ฐ์„ ํฌ๊ธฐ๊ฐ€ 2N × 2N์ธ ๊ฒฉ์ž๋กœ ๋‚˜๋ˆ„์–ด์ง„ ์–ผ์ŒํŒ์—์„œ ์—ฐ์Šตํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ์œ„์น˜ (r, c)๋Š” ๊ฒฉ์ž์˜ rํ–‰ c์—ด์„ ์˜๋ฏธํ•˜๊ณ , A[r][c]๋Š” (r, c)์— ์žˆ๋Š” ์–ผ์Œ์˜ ์–‘์„ ์˜๋ฏธํ•œ๋‹ค. A[r][c]๊ฐ€ 0์ธ ๊ฒฝ์šฐ ์–ผ์Œ์ด ์—†๋Š” ๊ฒƒ์ด๋‹ค.

ํŒŒ์ด์–ด์Šคํ†ฐ์„ ์‹œ์ „ํ•˜๋ ค๋ฉด ์‹œ์ „ํ•  ๋•Œ๋งˆ๋‹ค ๋‹จ๊ณ„ L์„ ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค. ํŒŒ์ด์–ด์Šคํ†ฐ์€ ๋จผ์ € ๊ฒฉ์ž๋ฅผ 2L × 2L ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๊ฒฉ์ž๋กœ ๋‚˜๋ˆˆ๋‹ค. ๊ทธ ํ›„, ๋ชจ๋“  ๋ถ€๋ถ„ ๊ฒฉ์ž๋ฅผ ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „์‹œํ‚จ๋‹ค. ์ดํ›„ ์–ผ์Œ์ด ์žˆ๋Š” ์นธ 3๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ๊ณผ ์ธ์ ‘ํ•ด์žˆ์ง€ ์•Š์€ ์นธ์€ ์–ผ์Œ์˜ ์–‘์ด 1 ์ค„์–ด๋“ ๋‹ค. (r, c)์™€ ์ธ์ ‘ํ•œ ์นธ์€ (r-1, c), (r+1, c), (r, c-1), (r, c+1)์ด๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์˜ ์นธ์— ์ ํžŒ ์ •์ˆ˜๋Š” ์นธ์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์ ์€ ์ •์ˆ˜์ด๋‹ค.

๋งˆ๋ฒ•์‚ฌ ์ƒ์–ด๋Š” ํŒŒ์ด์–ด์Šคํ†ฐ์„ ์ด Q๋ฒˆ ์‹œ์ „ํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋ชจ๋“  ํŒŒ์ด์–ด์Šคํ†ฐ์„ ์‹œ์ „ํ•œ ํ›„, ๋‹ค์Œ 2๊ฐ€์ง€๋ฅผ ๊ตฌํ•ด๋ณด์ž.

  1. ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ A[r][c]์˜ ํ•ฉ
  2. ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ ์ค‘ ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์นธ์˜ ๊ฐœ์ˆ˜

์–ผ์Œ์ด ์žˆ๋Š” ์นธ์ด ์–ผ์Œ์ด ์žˆ๋Š” ์นธ๊ณผ ์ธ์ ‘ํ•ด ์žˆ์œผ๋ฉด, ๋‘ ์นธ์„ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๋ฉ์–ด๋ฆฌ๋Š” ์—ฐ๊ฒฐ๋œ ์นธ์˜ ์ง‘ํ•ฉ์ด๋‹ค.

 

โ–ธ ์ž…๋ ฅ

์ฒซ์งธ ์ค„์— N๊ณผ Q๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ 2N๊ฐœ์˜ ์ค„์—๋Š” ๊ฒฉ์ž์˜ ๊ฐ ์นธ์— ์žˆ๋Š” ์–ผ์Œ์˜ ์–‘์ด ์ฃผ์–ด์ง„๋‹ค. r๋ฒˆ์งธ ์ค„์—์„œ c๋ฒˆ์งธ ์ฃผ์–ด์ง€๋Š” ์ •์ˆ˜๋Š” A[r][c] ์ด๋‹ค.

๋งˆ์ง€๋ง‰ ์ค„์—๋Š” ๋งˆ๋ฒ•์‚ฌ ์ƒ์–ด๊ฐ€ ์‹œ์ „ํ•œ ๋‹จ๊ณ„ L1, L2, ..., LQ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์ฃผ์–ด์ง„๋‹ค.

 

โ–ธ ์ถœ๋ ฅ

์ฒซ์งธ ์ค„์— ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ A[r][c]์˜ ํ•ฉ์„ ์ถœ๋ ฅํ•˜๊ณ , ๋‘˜์งธ ์ค„์— ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์นธ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋‹จ, ๋ฉ์–ด๋ฆฌ๊ฐ€ ์—†์œผ๋ฉด 0์„ ์ถœ๋ ฅํ•œ๋‹ค.

 

โ–ธ ์ œํ•œ

  • 2 ≤ N ≤ 6
  • 1 ≤ Q ≤ 1,000
  • 0 ≤ A[r][c] ≤ 100
  • 0 ≤ Li ≤ N

 

๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด

  • ๐Ÿฅ‡  ๋ฌธ์ œ ๋ ˆ๋ฒจ : ๊ณจ๋“œ 3
  • ๐Ÿ””  ๋ฌธ์ œ ์œ ํ˜• : ๊ตฌํ˜„, ๊ทธ๋ž˜ํ”„ ์ด๋ก , ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰, ์‹œ๋ฎฌ๋ ˆ์ด์…˜, ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰, ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰
  • ๐Ÿ’ฌ  ํ’€์ด ์–ธ์–ด : JAVA

 

๐Ÿค” ๋ฌธ์ œ ํ’€์ด

ํŒŒ์ด์–ด์Šคํ†ฐ์˜ ์‹œ์ „ ๋‹จ๊ณ„๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ๊ฒฉ์ž๋ฅผ 2L × 2L ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๊ฒฉ์ž๋กœ ๋‚˜๋ˆˆ๋‹ค.
    • ์‹œ์ „ํ•  ๋•Œ๋งˆ๋‹ค ๋‹จ๊ณ„ L์„ ๊ฒฐ์ •ํ•œ๋‹ค.
  2. ๋ชจ๋“  ๋ถ€๋ถ„ ๊ฒฉ์ž๋ฅผ ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „์‹œํ‚จ๋‹ค.
  3. ์–ผ์Œ์ด ์žˆ๋Š” ์นธ 3๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ๊ณผ ์ธ์ ‘ํ•ด์žˆ์ง€ ์•Š์€ ์นธ์€ ์–ผ์Œ์˜ ์–‘์ด 1 ์ค„์–ด๋“ ๋‹ค.
  4. ์œ„ ๊ณผ์ •์„ Q ๋งŒํผ ๋ฐ˜๋ณตํ•œ๋‹ค.

 

๋จผ์ €, ๋ถ€๋ถ„ ๊ฒฉ์ž๋ฅผ ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด์ž.

์•„๋ž˜์™€ ๊ฐ™์€ 3 x 3 ํฌ๊ธฐ์˜ ๋ถ€๋ถ„ ๊ฒฉ์ž๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž.

(0, 0) (0, 1) (0, 2)
(1, 0) (1, 1) (1, 2)
(2, 0) (2, 1) (2, 2)

                                   [ map ]

๊ฒฉ์ž๋ฅผ ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „์‹œํ‚ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

(2, 0) (1, 0) (0, 0)
(2, 1) (1, 1) (0, 1)
(2, 2) (1, 2) (0, 2)

                                  [ result ]

 

๊ฒฐ๊ณผ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณต์‹์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

result[i][j] = map[n-1-j][i]

 

์œ„ ๊ทœ์น™์„ ์‘์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

private static int[][] divide(int l) {
    int[][] tmp = new int[n][n];
    l = (int) Math.pow(2, l);
    for (int i = 0; i < n; i+=l) {
        for (int j = 0; j < n; j+=l) {
            rotate(i, j, l, tmp);
        }
    }

    return tmp;
}

private static void rotate(int x, int y, int l, int[][] tmp) {
    for (int i = 0; i < l; i++) {
        for (int j = 0; j < l; j++) {
            tmp[i+x][j+y] = map[x+l-1-j][y+i];
        }
    }
}

 

๋ถ€๋ถ„ ๊ฒฉ์ž 90๋„ ํšŒ์ „์„ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด,

์ด์ œ ๋ชจ๋“  ์–ผ์Œ ์นธ ์ฃผ์œ„๋ฅผ ํƒ์ƒ‰ํ•˜๋ฉฐ ์ธ์ ‘ ์–ผ์Œ ์นธ์ด 3๊ฐœ ๋ฏธ๋งŒ์ธ ์นธ์„ ์ฐพ์•„ ์–ผ์Œ์„ 1 ๋…น์—ฌ์ค˜์•ผ ํ•œ๋‹ค.

 

์ด๋•Œ, ์ฃผ์˜ํ•  ์ ์€ map ๋ฐฐ์—ด์„ ์ง์ ‘์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์–ผ์Œ์ด ์ค„์–ด๋“  ๋’ค ์ƒํƒœ๊ฐ€ ๋‹ค๋ฅธ ์นธ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ tmp ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•ด map์˜ ์ƒํƒœ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์–ผ์Œ์„ ๋…น์ธ ๊ฒฐ๊ณผ๋งŒ ๋”ฐ๋กœ ์ €์žฅํ•ด๋‘์—ˆ๋‹ค.

private static int[][] melt() {
    int[][] tmp = new int[n][n];
    for (int i = 0; i < n; i++) {
        tmp[i] = Arrays.copyOf(map[i], n); // n์€ ๋ณต์‚ฌ ํ•  ๊ธธ์ด
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (map[i][j] == 0) continue;
            
            int cnt = 0; // ์ธ์ ‘ํ•œ ์–ผ์Œ์ด ์žˆ๋Š” ์นธ์˜ ๊ฐœ์ˆ˜
            for (int d = 0; d < 4; d++) {
                int nx = i + dx[d];
                int ny = j + dy[d];

                if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                    if (map[nx][ny] > 0) cnt++;
                }
            }

            if (cnt < 3) tmp[i][j]--; // 3๊ฐœ ๋ฏธ๋งŒ์ด๋ผ๋ฉด ์–ผ์Œ ๋…น์ด๊ธฐ
        }
    }

    return tmp;
}

 

์œ„ ๊ณผ์ •์„ Q ๋งŒํผ ๋ฐ˜๋ณตํ•œ ๋’ค, ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ์˜ ํ•ฉ๊ณผ ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์นธ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค.

๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰(BFS)๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ์˜ ์นธ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ฉด์„œ ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ์˜ ํ•ฉ๋„ ๊ฐ™์ด ๊ตฌํ•ด์คฌ๋‹ค.

private static void biggest() {
    Queue<int[]> que = new LinkedList<>();
    boolean[][] checked = new boolean[n][n];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            total += map[i][j]; // ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ์˜ ํ•ฉ
            
            if (map[i][j] > 0 && !checked[i][j]) {
                que.offer(new int[]{i, j});
                checked[i][j] = true;
                
                int cnt = 1; // ํ˜„์žฌ ์˜์—ญ์˜ ์นธ์˜ ๊ฐœ์ˆ˜
                 while (!que.isEmpty()) {
                    int[] now = que.poll();

                    for (int d = 0; d < 4; d++) {
                        int nx = now[0] + dx[d];
                        int ny = now[1] + dy[d];

                        if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                            if (map[nx][ny] > 0 && !checked[nx][ny]) {
                                que.offer(new int[]{nx, ny});
                                checked[nx][ny] = true;
                                cnt++;
                            }
                        }
                    }
                }
                
                max = Math.max(max, cnt);
            }
        }
    }
}

 

์œ„ ํ’€์ด์˜ ์ฝ”๋“œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ „์ฒด์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

โœ” ์ฝ”๋“œ

๋ฉ”๋ชจ๋ฆฌ : 64392KB
์‹œ๊ฐ„ : 248ms
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int n, q;
    static int[][] map;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int total, max;
    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());
        q = Integer.parseInt(st.nextToken()); // ํŒŒ์ด์–ด์Šคํ†ฐ์„ ์ด Q๋ฒˆ ์‹œ์ „

        n = (int) Math.pow(2, n);
        map = new int[n][n]; // 2N × 2N์ธ ๊ฒฉ์ž
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int[] l = new int[q]; // ๋งˆ๋ฒ•์‚ฌ ์ƒ์–ด๊ฐ€ ์‹œ์ „ํ•œ ๋‹จ๊ณ„
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < q; i++) {
            l[i] = Integer.parseInt(st.nextToken());
        }

        for (int i = 0; i < q; i++) {
            map = divide(l[i]); // ๋ถ€๋ถ„ ๊ฒฉ์ž ๋‚˜๋ˆ„๊ธฐ
            map = melt(); // ์ธ์ ‘ํ•œ ์–ผ์Œ ์นธ์ด 3๊ฐœ ๋ฏธ๋งŒ์ธ ์นธ ์ฐพ์•„ ์–ผ์Œ ๋…น์ด๊ธฐ
        }

        // ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ์˜ ํ•ฉ, ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์นธ์˜ ๊ฐœ์ˆ˜
        total = max = 0;
        biggest();

        StringBuilder sb = new StringBuilder();
        sb.append(total).append("\n").append(max);

        System.out.println(sb.toString());

        br.close();
    }

    private static int[][] divide(int l) {
        int[][] tmp = new int[n][n];
        l = (int) Math.pow(2, l);
        for (int i = 0; i < n; i+=l) {
            for (int j = 0; j < n; j+=l) {
                rotate(i, j, l, tmp); // ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „
            }
        }

        return tmp;
    }

    private static void rotate(int x, int y, int l, int[][] tmp) {
        for (int i = 0; i < l; i++) {
            for (int j = 0; j < l; j++) {
                tmp[i+x][j+y] = map[x+l-1-j][y+i];
            }
        }
    }
    
    private static int[][] melt() {
        int[][] tmp = new int[n][n];
        for (int i = 0; i < n; i++) {
            tmp[i] = Arrays.copyOf(map[i], n);
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (map[i][j] == 0) continue;
            
                int cnt = 0; // ์ธ์ ‘ํ•œ ์–ผ์Œ์ด ์žˆ๋Š” ์นธ์˜ ๊ฐœ์ˆ˜
                for (int d = 0; d < 4; d++) {
                    int nx = i + dx[d];
                    int ny = j + dy[d];

                    if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                        if (map[nx][ny] > 0) cnt++;
                    }
                }

                if (cnt < 3) tmp[i][j]--; // 3๊ฐœ ๋ฏธ๋งŒ์ด๋ผ๋ฉด ์–ผ์Œ ๋…น์ด๊ธฐ
            }
        }

        return tmp;
    }
    
    private static void biggest() {
        Queue<int[]> que = new LinkedList<>();
        boolean[][] checked = new boolean[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                total += map[i][j]; // ๋‚จ์•„์žˆ๋Š” ์–ผ์Œ์˜ ํ•ฉ
                if (map[i][j] > 0 && !checked[i][j]) {
                    que.offer(new int[]{i, j});
                    checked[i][j] = true;
                    int cnt = 1; // ํ˜„์žฌ ์˜์—ญ์˜ ์นธ์˜ ๊ฐœ์ˆ˜

                    while (!que.isEmpty()) {
                        int[] now = que.poll();

                        for (int d = 0; d < 4; d++) {
                            int nx = now[0] + dx[d];
                            int ny = now[1] + dy[d];

                            if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                                if (map[nx][ny] > 0 && !checked[nx][ny]) {
                                    que.offer(new int[]{nx, ny});
                                    checked[nx][ny] = true;
                                    cnt++;
                                }
                            }
                        }
                    }
                    
                    max = Math.max(max, cnt);
                }
            }
        }
    }
}

 

๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ๋ชจ๋“  ๋ถ€๋ถ„ ๊ฒฉ์ž๋ฅผ ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „ํ•˜๋Š” ๋ถ€๋ถ„ ๋•Œ๋ฌธ์— ๊ฝค๋‚˜ ์• ๋ฅผ ๋จน์—ˆ๋‹ค.

๊ฑฐ๊ธฐ๋‹ค ๋ฌธ์ œ๋ฅผ ์ž˜๋ชป ์ฝ์–ด ๋ฌธ์ œ์— ๋‚˜์˜จ ์˜ˆ์‹œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ์—๋„ ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋ชจํ–ˆ๋‹ค.

๋ฌธ์ œ๋ฅผ ์ข€ ๋” ๊ผผ๊ผผํžˆ ์ฝ๋Š” ์Šต๊ด€๊ณผ ๊ตฌํ˜„ ๋ฌธ์ œ๋ฅผ ๋” ๋งŽ์ด ํ’€์–ด๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค...โญ