반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-19 00:03
관리 메뉴

ImJay

[BOJ/Java] 21610. 마법사 상어와 비바라기 본문

알고리즘/구현

[BOJ/Java] 21610. 마법사 상어와 비바라기

ImJay 2024. 1. 29. 23:17
반응형

[BOJ/Java] 21610. 마법사 상어와 비바라기

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net


해설

풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        // 입력 받기
        String input = br.readLine();
        StringTokenizer st = new StringTokenizer(input);
        int n = Integer.parseInt(st.nextToken()); // 격자의 크기
        int m = Integer.parseInt(st.nextToken()); // 이동 횟수

        // 격자 상태 입력 받기
        int[][] water = new int[n][n]; // 각 바구니의 물의 양 저장
        for (int x = 0; x < n; x++) {
            input = br.readLine();
            st = new StringTokenizer(input);
            for (int y = 0; y < n; y++) {
                water[x][y] = Integer.parseInt(st.nextToken());
            }
        }

        // 이동 방향 정의
        int[][] direction = {{0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}};
        // 초기 비구름 위치 정의
        int[][] start = {{n - 1, 0}, {n - 1, 1}, {n - 2, 0}, {n - 2, 1}};
        // 비구름의 상태를 저장할 배열 초기화
        boolean[][] cloud = new boolean[n][n];
        for (int[] s : start) {
            cloud[s[0]][s[1]] = true; // 초기 비구름 위치 표시
        }

        // 이동 명령 처리
        for (int i = 0; i < m; i++) {
            input = br.readLine();
            st = new StringTokenizer(input);

            int d = Integer.parseInt(st.nextToken()); // 이동 방향
            int r = Integer.parseInt(st.nextToken()); // 이동 거리

            int dx = direction[d - 1][0] * (r % n); // x 방향 이동 거리
            int dy = direction[d - 1][1] * (r % n); // y 방향 이동 거리
            int newX, newY;

            // 구름 이동 및 비가 내려 물의 양 증가
            boolean[][] afterCloud = new boolean[n][n];
            for (int x = 0; x < n; x++) {
                for (int y = 0; y < n; y++) {
                    if (cloud[x][y]) {
                        // 구름의 이동
                        newX = x + dx;
                        newY = y + dy;
                        if (newX < 0) newX = n + x + dx;
                        else if (newX > n - 1) newX = x + dx - n;
                        if (newY < 0) newY = n + y + dy;
                        else if (newY > n - 1) newY = y + dy - n;

                        // 비가 내려 물의 양 증가
                        afterCloud[newX][newY] = true;
                        water[newX][newY]++;
                    }
                }
            }

            // 물복사버그 마법 수행
            for (int x = 0; x < n; x++) {
                for (int y = 0; y < n; y++) {
                    if (cloud[x][y]) {
                        afterCloud[x][y] = false; // 구름 사라짐
                        int count = 0; // 대각선 방향의 물이 있는 바구니 수
                        for (int j = 1; j < 8; j += 2) {
                            newX = x + direction[j][0];
                            newY = y + direction[j][1];
                            if (0 <= newX && newX < n && 0 <= newY && newY < n) {
                                if (water[newX][newY] != 0) {
                                    count++;
                                }
                            }
                        }
                        water[x][y] += count; // 물의 양 증가
                    }
                }
            }

            // 구름 생성 및 물의 양 변동 처리
            for (int x = 0; x < n; x++) {
                for (int y = 0; y < n; y++) {
                    if (cloud[x][y]) {
                        afterCloud[x][y] = false; // 구름 사라짐
                        // 구름이 사라진 칸이 아니고 물의 양이 2 이상인 경우 구름 생성 및 물의 양 변동
                        if (water[x][y] >= 2) {
                            afterCloud[x][y] = true; // 구름 생성
                            water[x][y] -= 2; // 물의 양 감소
                        }
                    }
                }
            }

            // 구름 상태 갱신
            for (int x = 0; x < n; x++) {
                for (int y = 0; y < n; y++) {
                    cloud[x][y] = afterCloud[x][y];
                }
            }
        }

        // 남아있는 물의 양 합산
        int ans = 0;
        for (int x = 0; x < n; x++) {
            for (int y = 0; y < n; y++) {
                ans += water[x][y];
            }
        }
        sb.append(ans);

        // 결과 출력
        System.out.print(sb);
    }
}

 

반응형

'알고리즘 > 구현' 카테고리의 다른 글

[BOJ/Java] 1244. 스위치 켜고 끄기  (1) 2024.01.29
[BOJ/Java] 17144. 미세먼지 안녕!  (0) 2024.01.29
[BOJ/Java] 3985. 롤 케이크  (0) 2024.01.29
[BOJ/Java] 2999. 비밀 이메일  (2) 2024.01.24
[BOJ/Java] 13300. 방 배정  (1) 2024.01.23
Comments