4 minute read

πŸ“Œ λ‚œμ΄λ„

πŸ₯‡ Gold 3


πŸ“Œ 문제

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

image

image

image


πŸ“Œ 풀이

이 문제λ₯Ό 처음 보자 λ“  생각은 N1913 λ‹¬νŒ½μ΄ 문제 μ˜€λ‹€.
ν•˜μ§€λ§Œ, κ·Έ λ‹Ήμ‹œ 문제λ₯Ό ν’€ λ•Œ, 정석적인 방법인 μ€‘μ•™μ—μ„œ νΌμ Έλ‚˜κ°€λŠ” 방법이 μ•„λ‹ˆλΌ, 외각μͺ½μ—μ„œλΆ€ν„° 타고 λ“€μ–΄μ˜€λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•΄μ„œ, λ‹€μ‹œ μ€‘μ•™μ—μ„œ νΌμ§€λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„μ„ ν•˜λ €κ³  ν•˜λ‹ˆκΉŒ λ„ˆλ¬΄λ‚˜λ„ μ–΄λ €μ› λ‹€.

처음 1μ‹œκ°„λ™μ•ˆμ€ μ€‘μ•™μ—μ„œ νΌμ Έλ‚˜κ°€λŠ” 방법에 λŒ€ν•΄μ„œ κ³ λ―Όν–ˆλ‹€.
λ‹€μŒ 그림처럼 쀑앙은 1κ°œλΆ€ν„° μ‹œμž‘ν•΄μ„œ 2, 4, 6, 8...와 같은 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•˜λ €κ³  ν•˜μ˜€λ‹€.

image

ν•˜μ§€λ§Œ λ„ˆλ¬΄λ‚˜λ„ μ–΄λ €μ›Œμ„œ κ΅¬μƒν•˜λŠ” 것을 ν¬κΈ°ν•˜κ³  λ‹€λ₯Έ 방법을 μƒκ°ν•˜κΈ° μ‹œμž‘ν–ˆλ‹€.
κ·ΈλŸ¬λ‹€κ°€ 되게 λ³΅μž‘ν•œ λ‹€λ₯Έ 방법을 λ– μ˜¬λ ΈλŠ”λ°, λ°”λ‘œ λ‹€μŒκ³Ό 같이 크기가 1λΆ€ν„° μ‹œμž‘ν•˜μ—¬ 2κ·Έλ£Ήλ§ˆλ‹€ 1μ”© μ¦κ°€ν•˜λ©΄μ„œ, λ°©ν–₯은 ν•œ 그룹이 λλ‚˜λ©΄ λ°”λ‘œ λ°”λ€ŒλŠ” 그런 λ°©μ‹μ˜ μ€‘μ•™μ—μ„œ λ»—μ–΄κ°€λŠ” λ°©λ²•μ΄μ˜€λ‹€.

image

이후, 이λ₯Ό μ΄μš©ν•˜μ—¬ 토넀이도λ₯Ό μ΄λ™μ‹œν‚€κ³ , 토넀이도가 μ΄λ™ν•˜λ©΄ λͺ¨λž˜κ°€ 움직일 수 있게, MoveSand ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬, λͺ¨λž˜λ₯Ό μ΄λ™μ‹œμΌœ μ£Όμ—ˆλ‹€.
μ΄λ•Œ SLR와 SLCλ₯Ό μ΄μš©ν•˜μ—¬ λͺ¨λž˜κ°€ 움직여야 ν•˜λŠ” μœ„μΉ˜λ₯Ό κ΅¬ν•΄μ£Όμ—ˆλ‹€.
ν•˜μ§€λ§Œ μ™Όμͺ½μœΌλ‘œ 이동은 잘 λ˜μ—ˆμ§€λ§Œ, 이λ₯Ό μƒν•˜μ’Œμš°μ— 맞좰 κ΅¬ν˜„ν•΄λ‚΄κΈ° μœ„ν•΄μ„œ λ‹€μŒκ³Ό 같이 2차원 μ’Œν‘œλ₯Ό κ΅¬ν•΄μ„œ 식을 λ„μΆœν•΄λ‚΄μ—ˆλ‹€.

image

일단 2차원 배열은 x, yλ₯Ό 각각 Row, Col이라 ν–ˆμ„ λ•Œ, 이λ₯Ό μ’Œν‘œν‰λ©΄μœΌλ‘œ μΉ˜ν™˜ν•΄μ„œ λ‚˜νƒœλ‚΄λ©΄ λ‹€μŒκ³Ό 같은 μ’Œν‘œν‰λ©΄μ΄ λ‚˜νƒ€λ‚˜κ²Œ λœλ‹€.
μ²˜μŒμ— SLR와 SLC은 A점을 κΈ°μ€€μœΌλ‘œ μ μ—ˆλ‹€.
이 문제의 λͺ¨λž˜λ₯Ό μ›€μ§μ΄λŠ” 방법은 Aλ₯Ό κΈ°μ€€μœΌλ‘œ 봀을 λ•Œ, μƒν•˜λŒ€μΉ­μ΄λ―€λ‘œ, λŒλ¦¬λŠ” μ—°μ‚° λŒ€μ‹  λŒ€μΉ­μ΄λ™μ‹œμΌœλ„ λ˜‘κ°™μ΄ μž‘λ™ν•œλ‹€.
λ”°λΌμ„œ Dλ₯Ό κ΅¬ν•˜λ €λ©΄ y좕에 점을 λŒ€μΉ­μ΄λ™ μ‹œν‚€λ©΄ λ˜λ―€λ‘œ, 즉 row와 col값을 μ„œλ‘œ λ°”κΏ”μ€€λ‹€.
C점은 A점을 y좕에 λŒ€μΉ­μ΄λ™ μ‹œν‚€λ©΄ λ˜λ―€λ‘œ, 즉 col에 -1을 κ³±ν•΄μ£Όλ©΄ λœλ‹€.
B점은 D점을 x좕에 λŒ€μΉ­μ΄λ™ μ‹œν‚€λ©΄ λ˜λ―€λ‘œ, Aλ₯Ό κΈ°μ€€μœΌλ‘œ row와 col을 λ°”κΏ”μ€€ ν›„, row에 -1을 더해주면 λœλ‹€.

μ΄λ•Œ, μ΄λ™μ‹œν‚¨ 점이 field의 λ°”κΉ₯이라면, OutSand값에 λ‚˜κ°„κ°’μ„ 더해주고, μ•„λ‹ˆλ©΄ ν•„λ“œμœ„μ˜ int Sand에 더해주면 λœλ‹€.

μ–΄μ œ ν‘Ό κ³¨λ“œ3짜리 νŒŒμ΄μ–΄λ³Όλ³΄λ‹€λŠ” μ‰¬μš΄ 문제인 것 κ°™μ•˜μ§€λ§Œ, μƒν•˜μ’Œμš°λ‘œ λŒλ¦¬λŠ” λ¬Έμ œκ°€ λ‚˜μ™€μ„œ μˆ˜ν•™μ μœΌλ‘œ μ–΄λ €μš΄ λ¬Έμ œμ˜€λ˜ 것 κ°™λ‹€.

κ·Έλž˜λ„ ν’€μ–΄λ‚΄λ‹ˆκΉŒ λΏŒλ“―ν–ˆλ‹€.. 😎


πŸ“Œ Code

package BOJ.Implements;

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

public class N20057 {
    static int N;
    static int[][] field;
    static int OutSand = 0;
    static final int[] DR = {0, 1, 0, -1};
    static final int[] DC = {-1, 0, 1, 0};
    static final int[] SLR = {-2, -1, -1, -1, 0, 1, 1, 1, 2, 0};
    static final int[] SLC = {0, -1, 0, 1, -2, -1, 0, 1, 0, -1};
    static final int[] SLW = {2, 10, 7, 1, 5, 10, 7, 1, 2};


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        StringTokenizer st;
        field = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                field[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        //ShowAll(new int[]{N / 2, N / 2});
        Tornado();
        System.out.println(OutSand);
    }

    static void Tornado() {
        int[] pos = new int[]{N / 2, N / 2};
        int dir = 0;
        OutSand = 0;
        int area = 1;
        boolean flag = true;
        while (true) {
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < area; j++) {
                    pos = new int[]{pos[0] + DR[dir], pos[1] + DC[dir]};
                    if (pos[0] < 0 || pos[0] >= N || pos[1] < 0 || pos[1] >= N) {
                        return;
                    }
                    MoveSand(pos, dir);
                    //ShowAll(pos);
                }
                dir += 1;
                if (dir > 3) {
                    dir = 0;
                }
            }
            area += 1;
        }
    }

    static void MoveSand(int[] pos, int dir) {
        int adjx = 1;
        if (dir == 1 || dir == 2) {
            adjx = -1;
        }
        int sand = field[pos[0]][pos[1]];
        int remainSand = sand;
        field[pos[0]][pos[1]] = 0;
        for (int i = 0; i < SLW.length; i++) {
            if (dir % 2 == 0) {
                if (pos[0] + SLR[i] < 0 || pos[0] + SLR[i] >= N || pos[1] + SLC[i] * adjx < 0 || pos[1] + SLC[i] * adjx >= N) {
                    OutSand += sand * SLW[i] / 100;
                    remainSand -= sand * SLW[i] / 100;
                    continue;
                }
                field[pos[0] + SLR[i]][pos[1] + SLC[i] * adjx] += sand * SLW[i] / 100;
                remainSand -= sand * SLW[i] / 100;
            } else {
                if (pos[0] + SLC[i] * adjx < 0 || pos[0] + SLC[i] * adjx >= N || pos[1] + SLR[i] < 0 || pos[1] + SLR[i] >= N) {
                    OutSand += sand * SLW[i] / 100;
                    remainSand -= sand * SLW[i] / 100;
                    continue;
                }
                field[pos[0] + SLC[i] * adjx][pos[1] + SLR[i]] += sand * SLW[i] / 100;
                remainSand -= sand * SLW[i] / 100;
            }
        }
        if (dir % 2 == 0) {
            if (pos[0] + SLR[9] < 0 || pos[0] + SLR[9] >= N || pos[1] + SLC[9] * adjx < 0 || pos[1] + SLC[9] * adjx >= N) {
                OutSand += remainSand;
            } else {
                field[pos[0] + SLR[9]][pos[1] + SLC[9] * adjx] += remainSand;
            }
        } else {
            if (pos[0] + SLC[9] < 0 * adjx || pos[0] + SLC[9] * adjx >= N || pos[1] + SLR[9] < 0 || pos[1] + SLR[9] >= N) {
                OutSand += remainSand;
            } else {
                field[pos[0] + SLC[9] * adjx][pos[1] + SLR[9]] += remainSand;
            }
        }
    }

    static void ShowAll(int[] pos) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (pos[0] == i && pos[1] == j) {
                    System.out.print(field[i][j] + ")");
                } else {
                    System.out.print(field[i][j] + " ");
                }
            }
            System.out.println();
        }
        System.out.println("=====================================");
    }
}

package (이름); λ₯Ό λ•Œκ³ , class 이름을 Main으둜 λ³€κ²½ν•˜λ©΄ λœλ‹€.


πŸ“Œ μΆ”κ°€ 예제

[Input]
5
0 0 0 0 0
0 0 0 0 0
0 10 0 0 0
0 0 0 0 0
0 0 0 0 0

[Output]
10
[Input]
5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 10 0 0 0
0 0 0 0 0

[Output]
10
[Input]
5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 10 0
0 0 0 0 0

[Output]
10
[Input]
5
0 0 0 0 0
0 0 0 0 0
0 0 0 10 0
0 0 0 0 0
0 0 0 0 0

[Output]
10


개인 곡뢀 기둝용 λΈ”λ‘œκ·Έμž…λ‹ˆλ‹€.
ν‹€λ¦¬κ±°λ‚˜ 였λ₯˜κ°€ μžˆμ„ 경우 μ œλ³΄ν•΄μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.😁