[Algorithm] 백준_마법사 상어와 파이어볼_20056번 (JAVA) 🔥

2025. 4. 11. 16:27·Algorithm
목차
  1. 📝문제
  2. 💡풀이
  3. 🤔Review

📝문제

티어: 골드4

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

어른 상어가 마법사가 되었고, 파이어볼을 배웠다.

마법사 상어가 크기가 N×N인 격자에 파이어볼 M개를 발사했다. 가장 처음에 파이어볼은 각자 위치에서 이동을 대기하고 있다. i번 파이어볼의 위치는 (ri, ci), 질량은 mi이고, 방향은 di, 속력은 si이다. 위치 (r, c)는 r행 c열을 의미한다.

격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.

파이어볼의 방향은 어떤 칸과 인접한 8개의 칸의 방향을 의미하며, 정수로는 다음과 같다.

7 0 1
6   2
5 4 3

마법사 상어가 모든 파이어볼에게 이동을 명령하면 다음이 일들이 일어난다.

  1. 모든 파이어볼이 자신의 방향 di로 속력 si칸 만큼 이동한다.
    • 이동하는 중에는 같은 칸에 여러 개의 파이어볼이 있을 수도 있다.
  2. 이동이 모두 끝난 뒤, 2개 이상의 파이어볼이 있는 칸에서는 다음과 같은 일이 일어난다.
    1. 같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.
    2. 파이어볼은 4개의 파이어볼로 나누어진다.
    3. 나누어진 파이어볼의 질량, 속력, 방향은 다음과 같다.
      1. 질량은 ⌊(합쳐진 파이어볼 질량의 합)/5⌋이다.
      2. 속력은 ⌊(합쳐진 파이어볼 속력의 합)/(합쳐진 파이어볼의 개수)⌋이다.
      3. 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수이면, 방향은 0, 2, 4, 6이 되고, 그렇지 않으면 1, 3, 5, 7이 된다.
    4. 질량이 0인 파이어볼은 소멸되어 없어진다.

마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 구해보자.

입력

첫째 줄에 N, M, K가 주어진다.

둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다.

서로 다른 두 파이어볼의 위치가 같은 경우는 입력으로 주어지지 않는다.

출력

마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 출력한다.

 

💡풀이

문제 유형

구현

시뮬레이션

 

걸린 시간

어제 두시간 풀다가 포기 + 오늘 100분

 

풀이 방법 도출(주석참고)

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

class Main {
    static ArrayList<Node>[][] temp;
    static int N;
    static int[] dx = {-1, -1, 0, 1, 1, 1, 0, -1};
    static int[] dy = {0, 1, 1, 1, 0, -1, -1, -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());
        int M = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());

        // 1) 한 칸에 여러 개의 파이어볼이 들어갈 수 있으므로 ArrayList<Node>[][]로 선언해주었다.
        ArrayList<Node>[][] fireball = new ArrayList[N][N];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                fireball[i][j] = new ArrayList<>();
            }
        }

        // 2) 입력받은 파이어볼을 배열 리스트에 질량, 속도, 방향의 정보를 넣는다.
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int r = Integer.parseInt(st.nextToken()) - 1;
            int c = Integer.parseInt(st.nextToken()) - 1;
            int m = Integer.parseInt(st.nextToken());
            int s = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());

            fireball[r][c].add(new Node(m, s, d));
        }

        // 3) 새로운 격자를 만들어 이동 후 파이어볼의 위치를 담는다.
        for (int t = 0; t < K; t++) {
            temp = new ArrayList[N][N];

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    temp[i][j] = new ArrayList<>();
                }
            }

            // 4) 모든 파이어볼이 자신의 방향 d로 속력 s칸 만큼 이동한다
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    for (Node node : fireball[i][j]) {
                        moveFireball(i, j, node.m, node.s, node.d);
                    }
                }
            }

            //5) 얕은복사(참조복사)를 하여 fireball은 이제 temp의 내용을 가리킨다
            fireball = temp;

            // 6) 이동이 모두 끝난 뒤, 2개 이상의 파이어볼 나누기
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    int size = fireball[i][j].size();
                    if (size >= 2) {
                        int mSum = 0;
                        int sSum = 0;
                        int evenD = 0;
                        int oddD = 0;

                        for (Node node : fireball[i][j]) {
                            mSum += node.m;
                            sSum += node.s;
                            if (node.d % 2 == 0) {
                                evenD++;
                            } else {
                                oddD++;
                            }
                        }

                        int[] newD = {};
                        if (evenD == size || oddD == size) {
                            newD = new int[]{0, 2, 4, 6};
                        } else {
                            newD = new int[]{1, 3, 5, 7};
                        }

                        int newM = (int) Math.floor(mSum / 5);
                        int newS = (int) Math.floor(sSum / size);

                        // 7) 현재 칸 초기화
                        fireball[i][j] = new ArrayList<>();

                        // 8) 현재 칸에 분할 된 4개의 파이어볼 추가
                        if (newM > 0) {
                            for (int k = 0; k < 4; k++) {
                                fireball[i][j].add(
                                        new Node(newM, newS, newD[k]));
                            }
                        }
                    }
                }
            }
        }

        int sum = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                for (Node node : fireball[i][j]) {
                    sum += node.m;
                }
            }
        }

        System.out.println(sum);
    }

    public static void moveFireball(int x, int y, int m, int s, int d) {
        int nx = (x + dx[d] * s) % N;
        int ny = (y + dy[d] * s) % N;

        if (nx < 0) {
            nx = N + nx;
        }
        if (ny < 0) {
            ny = N + ny;
        }
        temp[nx][ny].add(new Node(m, s, d));
    }
}

class Node {
    int m;
    int s;
    int d;

    public Node(int m, int s, int d) {
        this.m = m;
        this.s = s;
        this.d = d;
    }
}

 

🤔Review

나..문해력이 안 좋은 거 가타..

'Algorithm' 카테고리의 다른 글

[Algorithm] 백준_포도주 시식_2156번 (JAVA) 🍇  (1) 2025.04.15
[Algorithm] 백준_뱀과 사다리 게임_16928번 (JAVA) 🐍  (0) 2025.04.14
[Algorithm] 백준_컨베이어 벨트 위의 로봇_20055번 (JAVA) 🤖  (1) 2025.04.10
[Algorithm] 백준_마법사 상어와 비바라기_21610번 (JAVA)🪄  (1) 2025.04.09
[Algorithm] 백준_상어 초등학교_21608번 (JAVA) 🏫  (1) 2025.04.09
  1. 📝문제
  2. 💡풀이
  3. 🤔Review
'Algorithm' 카테고리의 다른 글
  • [Algorithm] 백준_포도주 시식_2156번 (JAVA) 🍇
  • [Algorithm] 백준_뱀과 사다리 게임_16928번 (JAVA) 🐍
  • [Algorithm] 백준_컨베이어 벨트 위의 로봇_20055번 (JAVA) 🤖
  • [Algorithm] 백준_마법사 상어와 비바라기_21610번 (JAVA)🪄
dev_ajrqkq
dev_ajrqkq
알고리즘 천재가 될 거야
  • dev_ajrqkq
    기록이 자산이다
    dev_ajrqkq
  • 전체
    오늘
    어제
    • 분류 전체보기 (147)
      • Front-end (0)
      • Back-end (11)
        • Spring (1)
        • Java (8)
      • CS (9)
        • 데이터베이스 (5)
        • 네트워크 (4)
      • Algorithm (80)
      • 이것저것 (0)
      • 버그잡기 (1)
      • TIL (37)
      • 후기 (1)
      • 취준 (0)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      개발자취업
      티스토리챌린지
      99클럽
      항해99
      코딩테스트준비
      TypeScript
      Til
      오블완
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    dev_ajrqkq
    [Algorithm] 백준_마법사 상어와 파이어볼_20056번 (JAVA) 🔥
    상단으로

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.