Java/BOJ

[BOJ] 백준 21610. 마법사 상어와 비바라기

동구름이 2024. 4. 29. 21:05

문제

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

 


풀이

 전형적인 삼성 역량 테스트의 구현 문제입니다. 

 

우선 문제를 통해 다음의 동작으로 메서드를 구분해볼 수 있습니다.

 

1. 구름 이동 (moveClouds)

2. 비 내리기(rain)

3. 물 복사(copyWater)

4. 구름 만들기(makeClouds)

 

각 단계별 메서드를 따라 구현을 해주면 되는데, 이 문제에서 생각해 볼 것은 1번 열과 N번 열, 그리고 1번 행과 N번 행이 연결된 것을 구현하는 것입니다. 이것은 % 연산자를 통해 간단히 구현할 수 있습니다.

 

 그리고 이 문제의 전반적인 부분에서 조심해야하는 것은, 구름을 이동하거나 물을 복사하는 동작에서, 수정된 데이터를 사용하는 것을 주의해야합니다. 그것을 방지하기 위해 ArrayList 에 담아 수정된 데이터를 사용하는 것을 막았습니다.

 

 아래는 소스 코드입니다.

 


소스 코드

import java.util.ArrayList;
import java.util.Scanner;

public class B21610_마법사상어와비바라기 {
    static int N,M;
    static int[][] map;
    static int[][] clouds;
    static class Movement{
        int d;
        int s;
        Movement(int d, int s){
            this.d=d;
            this.s=s;
        }
    }
    static int[] dr = {0,-1,-1,-1,0,1,1,1};
    static int[] dc = {-1,-1,0,1,1,1,0,-1};

    static ArrayList<Movement> list = new ArrayList<>();
    static ArrayList<int[]> waters;
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        input();
        magic();
    }

    static void input(){
        N = sc.nextInt();
        M = sc.nextInt();
        map = new int[N][N];
        clouds = new int[N][N];
        for(int r =0;r<N;r++){
            for(int c=0;c<N;c++){
                map[r][c] = sc.nextInt();
            }
        }
        for(int i = 0;i<M;i++){
            int d = sc.nextInt()-1;
            int s = sc.nextInt();
            list.add(new Movement(d,s));
        }
    }

    static void magic(){
        for(int r = N-2;r<N;r++){
            for(int c=0;c<2;c++){
                clouds[r][c] = 1;
            }
        }
        for(int i = 0; i<M;i++) {
            int d = list.get(i).d;
            int s = list.get(i).s;
            moveClouds(d,s);
            waters = new ArrayList<>();
            rain();
            copyWater();
            makeCloud();
        }
        System.out.println(getSum());

    }

    static void moveClouds(int d, int s){
        ArrayList<int[]> nows = new ArrayList<>();
        for(int r =0;r<N;r++){
            for(int c=0;c<N;c++){
                if(clouds[r][c]==1){
                    nows.add(new int[]{r,c});
                    clouds[r][c] = 0;
                }
            }
        }

        for(int i=0;i<nows.size();i++){
            int nowR = nows.get(i)[0];
            int nowC = nows.get(i)[1];
            int nextR = 0;
            int nextC = 0;
            if(nowR+dr[d]*s>=0) nextR = (nowR+dr[d]*s)%N;
            else{
                if(Math.abs(nowR+dr[d]*s)%N==0) nextR = 0;
                else nextR = N-Math.abs(nowR+dr[d]*s)%N;
            }

            if(nowC+dc[d]*s>=0) nextC = (nowC+dc[d]*s)%N;
            else{
                if(Math.abs(nowC+dc[d]*s)%N==0) nextC = 0;
                else nextC = N-Math.abs(nowC+dc[d]*s)%N;
            }
            clouds[nextR][nextC] = 1;
        }
    }

    static void rain(){
        for(int r =0;r<N;r++){
            for(int c=0;c<N;c++){
                if(clouds[r][c]==1){
                   map[r][c]++;
                   clouds[r][c] = 0;
                   waters.add(new int[]{r,c});
                }
            }
        }
    }

    static void copyWater(){
        ArrayList<int[]> copyWaters = new ArrayList<>();
        for(int i=0;i<waters.size();i++){
            int r = waters.get(i)[0];
            int c = waters.get(i)[1];
            int cnt = 0;
            for(int d=1;d<8;d+=2){
                int idr = r+dr[d];
                int idc = c+dc[d];
                if(idr<0||idc<0||idr>=N||idc>=N) continue;
                if(map[idr][idc]>0) cnt++;

            }
            copyWaters.add(new int[]{r,c,cnt});
        }
        for(int i=0;i<copyWaters.size();i++){
            int r = copyWaters.get(i)[0];
            int c = copyWaters.get(i)[1];
            int cnt =copyWaters.get(i)[2];
            map[r][c] += cnt;
        }
    }
    static void makeCloud(){
        for(int r =0;r<N;r++){
            outer: for(int c=0;c<N;c++){
                if(map[r][c]>=2){
                    for(int i = 0;i<waters.size();i++){
                        if(r==waters.get(i)[0]&&c==waters.get(i)[1]) continue outer;
                    }
                    clouds[r][c] = 1;
                    map[r][c]-=2;
                }
            }
        }
    }
    static int getSum(){
        int sum = 0;
        for(int r =0;r<N;r++){
            for(int c=0;c<N;c++){
                sum+=map[r][c];
            }
        }
        return sum;
    }
}