[BOJ] 20056번 | λ§ˆλ²•μ‚¬ 상어와 νŒŒμ΄μ–΄λ³Ό (Java)

2024. 7. 25. 00:07ㆍCoding Test/BOJ

πŸ”—λ¬Έμ œ λ³΄λŸ¬κ°€κΈ°

 

 

πŸ§‘πŸ»‍πŸ’»ν’€μ΄ κ³Όμ •

λΉ‘κ΅¬ν˜„ λ¬Έμ œλŠ” μš”κ΅¬μ‚¬ν•­ λ³„λ‘œ λ©”μ„œλ“œλ₯Ό 잘 λ‚˜λˆ  κ΅¬ν˜„ν•˜λŠ” 게 μ€‘μš”ν•˜λ‹€κ³  μƒκ°ν•˜λŠ”λ°, μ΄λ ‡κ²Œ 해도 쀑간에 둜직이 잘λͺ»λ˜λ©΄ λ””λ²„κΉ…ν•˜κΈ°κ°€ 정말 μ–΄λ ΅λ„€μš”. μ €λŠ” νŒŒμ΄μ–΄λ³Όμ΄ 같은 μœ„μΉ˜μ— μžˆλŠ”μ§€ νŒŒμ•…ν•˜κΈ° μœ„ν•œ 2차원 Queue λ°°μ—΄, ν˜„μž¬ 맡에 μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Όλ“€μ„ κ΄€λ¦¬ν•˜λŠ” Queue μ΄λ ‡κ²Œ 2개λ₯Ό μ¨μ„œ ν’€μ—ˆμŠ΅λ‹ˆλ‹€. νμ—μ„œλŠ” νŒŒμ΄μ–΄λ³Ό 클래슀 정보λ₯Ό κ΄€λ¦¬ν•˜κ΅¬μš”.

class FireBall {
    FireBall(int row, int column, int mass, int velocity, int direction) {
        this.row = row;
        this.column = column;
        this.mass = mass;
        this.velocity = velocity;
        this.direction = direction;
    }

    int row, column, mass, velocity, direction;
}

 

BufferedReaderλ₯Ό 톡해 μž…λ ₯값을 λ°›μ•„μ£Όκ³ , 2차원 큐 λ°°μ—΄κ³Ό 관리 큐λ₯Ό μƒμ„±ν•΄μ€λ‹ˆλ‹€. 그리고 ν–‰, μ—΄, μ§ˆλŸ‰, 속도, λ°©ν–₯ 정보값을 μž…λ ₯ λ°›μ•„ 관리 큐에닀가 λ„£μ–΄μ£Όμ—ˆμ£ .

private static void initialize() throws Exception {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String[] args = br.readLine().split(" ");

    N = Integer.parseInt(args[0]);
    M = Integer.parseInt(args[1]);
    K = Integer.parseInt(args[2]);
    Field = new LinkedList[N][N];
    FireBalls = new LinkedList<>();

    // 1. 2차원 λ°°μ—΄ 각 μš”μ†Œλ§ˆλ‹€ 큐(Queue) 생성
    for (int r = 0; r < N; r++) {
        for (int c = 0; c < N; c++) {
            Field[r][c] = new LinkedList<FireBall>();
        }
    }

    // 2. ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Ό 정보λ₯Ό λ‹΄λŠ” FireBalls 큐에 μ΄ˆκΈ°κ°’ λ„£κΈ°
    for (int i = 0; i < M; i++) {
        args = br.readLine().split(" ");
        int row = Integer.parseInt(args[0]) - 1;
        int column = Integer.parseInt(args[1]) - 1;
        int mass = Integer.parseInt(args[2]);
        int velocity = Integer.parseInt(args[3]);
        int direction = Integer.parseInt(args[4]);

        FireBalls.add(new FireBall(row, column, mass, velocity, direction));
    }

    br.close();
}

 

μž…λ ₯κ°’ λ°›κΈ°λ₯Ό μ™„λ£Œν–ˆλ‹€λ©΄ νŒŒμ΄μ–΄λ³Όμ„ μ΄λ™μ‹œν‚€λŠ” moveFireBalls()와 λͺ¨λ‘ μ΄λ™ν•œ νŒŒμ΄μ–΄λ³Όλ“€μ„ μ²˜λ¦¬ν•˜λŠ” processFireBalls()λ₯Ό K번 λ°˜λ³΅ν•  κ²λ‹ˆλ‹€.

 

moveFireBalls()

ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Όμ˜ 개수(FireBalls.size())만큼 for 문을 λŒμ•„ λ‹€μŒ μœ„μΉ˜λ‘œ μ΄λ™μ‹œμΌœ 쀄 κ²λ‹ˆλ‹€. μ΄λ•Œ, λ¬Έμ œμ—μ„œ 주어진 맡은 λ¬΄ν•œ λ§΅μ΄λ―€λ‘œ 맡 밖을 λ„˜μ–΄κ°€λ„ λ‹€μ‹œ λ°˜λŒ€νŽΈμœΌλ‘œ λŒμ•„μ™€μ•Ό ν•©λ‹ˆλ‹€. 이λ₯Ό μ μš©ν•΄μ£ΌκΈ° μœ„ν•΄ λͺ¨λ“ˆλŸ¬ μ—°μ‚°(%)을 μ μš©ν–ˆμœΌλ©°, 음수일 κ²½μš°μ—λŠ” λͺ¨λ“ˆλŸ¬ 연산을 μ μš©ν•΄λ„ κ·ΈλŒ€λ‘œ 음수인 κ²½μš°κ°€ μžˆμœΌλ―€λ‘œ N만큼 μΆ”κ°€λ‘œ λ”ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

private static void moveFireBalls() {
    int size = FireBalls.size();

    for (int i = 0; i < size; i++) {
        FireBall fireBall = FireBalls.poll();
        int nextRow = (fireBall.row + RowDirections[fireBall.direction] * fireBall.velocity) % N;
        int nextColumn = (fireBall.column + ColumnDirections[fireBall.direction] * fireBall.velocity) % N;

        if (nextRow < 0)    nextRow += N;
        if (nextColumn < 0) nextColumn += N;

        fireBall.row = nextRow;
        fireBall.column = nextColumn;
        Field[nextRow][nextColumn].add(fireBall);
    }
}

 

processFireBalls()

전체 맡을 μˆœνšŒν•˜λ©΄μ„œ νŒŒμ΄μ–΄λ³Όμ˜ κ°œμˆ˜μ— 따라 λ‹€λ₯Έ 연산을 μ μš©ν•©λ‹ˆλ‹€.

  • νŒŒμ΄μ–΄λ³Όμ˜ κ°œμˆ˜κ°€ 1개인 경우 : 맡의 ν˜„μž¬ μœ„μΉ˜μ—μ„œ νŒŒμ΄μ–΄λ³Όμ„ λΉΌλ‚΄μ–΄ 관리 큐(FireBalls)에 λ„£μŠ΅λ‹ˆλ‹€.
  • νŒŒμ΄μ–΄λ³Όμ˜ κ°œμˆ˜κ°€ 2개 이상인 경우 : νŒŒμ΄μ–΄λ³Όμ„ ν•˜λ‚˜λ‘œ 합쳐 4개둜 λΆ„λ¦¬ν•˜λŠ” κ³Όμ • 진행 → splitFireBalls()
private static void processFireBalls() {
    for (int row = 0; row < N; row++) {
        for (int column = 0; column < N; column++) {
            // 같은 곳에 νŒŒμ΄μ–΄λ³Ό κ°œμˆ˜κ°€ 1개인 경우 -> 관리 큐에 λ„£κΈ°
            if (Field[row][column].size() == 1) {
                FireBalls.add(Field[row][column].poll());
            }

            // 같은 곳에 νŒŒμ΄μ–΄λ³Ό κ°œμˆ˜κ°€ 2개 이상인 경우 -> 4개둜 뢄리
            else if (Field[row][column].size() > 1) {
                splitFireBalls(row, column);
            }
        }
    }
}

 

splitFireBalls() λ©”μ„œλ“œλŠ” 같은 곳에 μžˆλŠ” 2개 μ΄μƒμ˜ νŒŒμ΄μ–΄λ³Όλ“€μ΄ ν•˜λ‚˜λ‘œ 합쳐져 4개둜 λΆ„λ¦¬λ˜λŠ” μš”κ΅¬μ‚¬ν•­μ„ κ·ΈλŒ€λ‘œ κ΅¬ν˜„ν•œ κ²ƒμž…λ‹ˆλ‹€.

private static void splitFireBalls(int row, int column) {
    int sumMass = 0, sumVelocity = 0, size = Field[row][column].size();
    boolean isAllEven = true, isAllOdd = true;

    while (!Field[row][column].isEmpty()) {
        FireBall fireBall = Field[row][column].poll();
        sumMass += fireBall.mass;
        sumVelocity += fireBall.velocity;

        if (fireBall.direction % 2 == 0)    isAllOdd = false;
        else                                isAllEven = false;
    }

    int newMass = sumMass / 5;
    int newVelocity = sumVelocity / size;

    if (newMass > 0) {
        for (int i = 0; i < 4; i++) {
            int newDirection = (isAllEven || isAllOdd) ? i * 2 : i * 2 + 1;
            FireBalls.add(new FireBall(row, column, newMass, newVelocity, newDirection));
        }
    }
}

 

μ΄λŸ¬ν•œ 과정을 K번 λ°˜λ³΅ν•œ ν›„, ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Όλ“€μ˜ μ§ˆλŸ‰ 합을 좜λ ₯ν•΄μ£Όλ©΄ μ •λ‹΅μž…λ‹ˆλ‹€.

private static int getFireBallMass() {
    int result = 0;

    for (FireBall fireBall : FireBalls) {
        result += fireBall.mass;
    }

    return result;
}

 

전체 μ†ŒμŠ€μ½”λ“œλŠ” μ•„λž˜μ— μžˆμŠ΅λ‹ˆλ‹€.

더보기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Queue;
import java.util.LinkedList;

class FireBall {
    FireBall(int row, int column, int mass, int velocity, int direction) {
        this.row = row;
        this.column = column;
        this.mass = mass;
        this.velocity = velocity;
        this.direction = direction;
    }

    int row, column, mass, velocity, direction;
}

public class BOJ20056 {
    private static int N, M, K;
    private static int[] RowDirections = { -1, -1, 0, 1, 1, 1, 0, -1 };
    private static int[] ColumnDirections = { 0, 1, 1, 1, 0, -1, -1, -1 };
    private static Queue<FireBall>[][] Field;
    private static Queue<FireBall> FireBalls;

    public static void main(String[] args) throws Exception {
        initialize();

        for (int i = 0; i < K; i++) {
            moveFireBalls();
            processFireBalls();
        }

        int answer = getFireBallMass();
        System.out.println(answer);
    }

    private static void moveFireBalls() {
        int size = FireBalls.size();

        for (int i = 0; i < size; i++) {
            FireBall fireBall = FireBalls.poll();
            int nextRow = (fireBall.row + RowDirections[fireBall.direction] * fireBall.velocity) % N;
            int nextColumn = (fireBall.column + ColumnDirections[fireBall.direction] * fireBall.velocity) % N;

            if (nextRow < 0)    nextRow += N;
            if (nextColumn < 0) nextColumn += N;

            fireBall.row = nextRow;
            fireBall.column = nextColumn;
            Field[nextRow][nextColumn].add(fireBall);
        }
    }

    private static void processFireBalls() {
        for (int row = 0; row < N; row++) {
            for (int column = 0; column < N; column++) {
                // 같은 곳에 νŒŒμ΄μ–΄λ³Ό κ°œμˆ˜κ°€ 2개 미만인 경우 -> ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Όμ„ κ΄€λ¦¬ν•˜λŠ” 큐(FireBalls)에 λ„£μ–΄μ£ΌκΈ°
                if (Field[row][column].size() == 1) {
                    FireBalls.add(Field[row][column].poll());
                }

                // 같은 곳에 νŒŒμ΄μ–΄λ³Ό κ°œμˆ˜κ°€ 2개 이상인 경우 -> 4개둜 뢄리
                else if (Field[row][column].size() > 1) {
                    splitFireBalls(row, column);
                }
            }
        }
    }

    private static void splitFireBalls(int row, int column) {
        int sumMass = 0, sumVelocity = 0, size = Field[row][column].size();
        boolean isAllEven = true, isAllOdd = true;

        while (!Field[row][column].isEmpty()) {
            FireBall fireBall = Field[row][column].poll();
            sumMass += fireBall.mass;
            sumVelocity += fireBall.velocity;

            if (fireBall.direction % 2 == 0)    isAllOdd = false;
            else                                isAllEven = false;
        }

        int newMass = sumMass / 5;
        int newVelocity = sumVelocity / size;

        if (newMass > 0) {
            for (int i = 0; i < 4; i++) {
                int newDirection = (isAllEven || isAllOdd) ? i * 2 : i * 2 + 1;
                FireBalls.add(new FireBall(row, column, newMass, newVelocity, newDirection));
            }
        }
    }

    private static int getFireBallMass() {
        int result = 0;

        for (FireBall fireBall : FireBalls) {
            result += fireBall.mass;
        }

        return result;
    }

    private static void initialize() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] args = br.readLine().split(" ");

        N = Integer.parseInt(args[0]);
        M = Integer.parseInt(args[1]);
        K = Integer.parseInt(args[2]);
        Field = new LinkedList[N][N];
        FireBalls = new LinkedList<>();

        // 1. 2차원 λ°°μ—΄ 각 μš”μ†Œλ§ˆλ‹€ 큐(Queue) 생성
        for (int r = 0; r < N; r++) {
            for (int c = 0; c < N; c++) {
                Field[r][c] = new LinkedList<FireBall>();
            }
        }

        // 2. ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” νŒŒμ΄μ–΄λ³Ό 정보λ₯Ό λ‹΄λŠ” FireBalls 큐에 μ΄ˆκΈ°κ°’ λ„£κΈ°
        for (int i = 0; i < M; i++) {
            args = br.readLine().split(" ");
            int row = Integer.parseInt(args[0]) - 1;
            int column = Integer.parseInt(args[1]) - 1;
            int mass = Integer.parseInt(args[2]);
            int velocity = Integer.parseInt(args[3]);
            int direction = Integer.parseInt(args[4]);

            FireBalls.add(new FireBall(row, column, mass, velocity, direction));
        }

        br.close();
    }
}
728x90
λ°˜μ‘ν˜•

'Coding Test > BOJ' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[BOJ] 8938번 | 사λƒ₯κΎΌ (Java)  (0) 2024.08.01
[BOJ] 2477번 | μ°Έμ™Έλ°­ (Java)  (0) 2024.07.30
[BOJ] 12904번 | A와 B (C++)  (0) 2024.03.28
[BOJ] 14891번 | ν†±λ‹ˆλ°”ν€΄ (C++)  (0) 2024.03.24
[BOJ] 2636번 | 치즈 (C++)  (1) 2024.03.22