유랑하는 나그네의 갱생 기록

だけど素敵な明日を願っている -HANABI, Mr.children-

etc./BOJ

[BOJ] 23289 온풍기 안녕! - Java

Madirony 2024. 10. 12. 20:29
728x90

1. 문제 링크

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


2. 문제 풀이

 이제 곧 기다리던 삼성 코딩 테스트죠? 구현만큼은 자신 있었던 (과거형) 저도 이번만큼은 긴장되네요. 그야 자소서 문항이 바뀌고 난 후 첫 시험이라 .. 코딩테스트도 변동이 있을 가능성도 없진 않을 테니까요. 그래서 예전 같았으면 그냥 배열 돌리기랑 bfs만 돌리고 갔을 텐데 이번엔 다릅니다. 몇 달 전에 큐빙을 풀긴 했지만 좀 제대로 된 플래티넘 구현 문제를 풀고 싶었습니다.

 

 가장 중요한 건 설계. 코드를 구현하기 전에 꼼꼼하게 조건을 숙지한 후 구현을 해야 합니다. 그래도 나름 짧은 코드로 만들어보고 싶었으나 코드가 좀 길게 나왔습니다.

 

1. 모든 온풍기에서 바람 나옴

2. 온도 조절

3. 온도 1 이상인 가장 바깥쪽 칸의 온도가 1씩 감소

4. 초콜릿 먹기

5. 조사하는 모든 칸의 온도가 K 이상이 되었는지 체크. K 이상이면 테스트를 중단. 아니면 1번부터 다시 시작.

 

대충 절차만 보면은 간단하죠. 근데 문제는 벽이 있다는 겁니다. 그래서 이 벽의 위치를 어떻게 저장해서 활용할지를 제일 먼저 생각해야 합니다. 그다음은 온풍기에서 바람이 나올 때 온도가 올라가는 부분을 어떻게 탐색해야 할지를 고려해야 하고.. 이 두 가지 조건만 해결되면 나머지 구현은 쉽습니다.

 

2-1. Simulation

while(!check()) {
    heating();
    control();
    chilling();
    chocolate++;
    if(100 < chocolate) break;
}

이 부분이 바로 시뮬레이션의 본체입니다. 저 메서드들을 구현하기만 하면 완성되는 겁니다.

 

2-2. Variable

static int R,C,K;
static int[][] map;

static class Node {
    int x, y;
    Node (int x, int y){
        this.x = x;
        this.y = y;
    }
}

static class Heater {
    int d, x, y;
    Heater (int d, int x, int y){
        this.d = d; this.x = x; this.y = y;
    }
}

static HashMap<Integer, HashSet<Integer>> downBlock = new HashMap<>();
static HashMap<Integer, HashSet<Integer>> upBlock = new HashMap<>();
static HashMap<Integer, HashSet<Integer>> leftBlock = new HashMap<>();
static HashMap<Integer, HashSet<Integer>> rightBlock = new HashMap<>();

static int[] dx = {0, 0, 0, -1, 1};
static int[] dy = {0, 1, -1, 0, 0};
static List<Node> checkList = new ArrayList<>();
static List<Heater> heaterList = new ArrayList<>();

물론 그 이전에 문제를 푸는데 필요한 데이터와 입력 값을 받아야 하는 부분을 먼저 생각해야겠지만요. HashMap이 왜 저렇게 많냐-고 묻는다면, 제 알량한 구현력이 저지른 실수라 답하겠습니다. 삼차원 배열로 데이터를 관리하면 좀 더 편하긴 했겠지만, "엥 굳이?"라는 생각이 들었습니다. 아 물론 Null check를 신경 쓰지 않으면 소스가 터져버리기 때문에 저도 저러한 방식을 선호하지는 않지만 그렇게 했습니다.

 

2-3. Input

map = new int[R][C];
for(int i = 0; i < R; i++){
    st = new StringTokenizer(br.readLine());
    for(int j = 0; j < C; j++){
        int tmp = Integer.parseInt(st.nextToken());
        switch(tmp){
            case 1: case 2: case 3: case 4:
                heaterList.add(new Heater(tmp, i, j));
                break;
            case 5:
                checkList.add(new Node(i, j));
                break;
        }
    }
}

입력 값으로 주어지는 맵 데이터를 굳이 그대로 받아야 할까요? 어차피 문제가 요구하는 건 맵의 온도입니다. 히터의 위치니 체크하는 배열의 인덱스니 하는 것들은 따로 리스트로 관리하도록 합시다.

 

int wallCnt = Integer.parseInt(br.readLine());
for(int i = 0; i < wallCnt; i++){
    st = new StringTokenizer(br.readLine());
    int tx = Integer.parseInt(st.nextToken())-1;
    int ty = Integer.parseInt(st.nextToken())-1;
    int flag = Integer.parseInt(st.nextToken());
    HashSet<Integer> set, set2;
    switch (flag){
        case 0:
            if(downBlock.containsKey(tx)){
                set = downBlock.get(tx);
                set.add(ty);
                downBlock.put(tx, set);
                set2 = upBlock.get(tx-1);
                set2.add(ty);
                upBlock.put(tx-1, set2);
            }
            else{
                set = new HashSet<>();
                set2 = new HashSet<>();
                set.add(ty);
                set2.add(ty);
                downBlock.put(tx, set);
                upBlock.put(tx-1, set2);
            }
            break;
        case 1:
            if(leftBlock.containsKey(tx)){
                set = leftBlock.get(tx);
                set.add(ty);
                leftBlock.put(tx, set);
                set2 = rightBlock.get(tx);
                set2.add(ty+1);
                rightBlock.put(tx, set2);
            }
            else{
                set = new HashSet<>();
                set2 = new HashSet<>();
                set.add(ty);
                set2.add(ty+1);
                leftBlock.put(tx, set);
                rightBlock.put(tx, set2);
            }
            break;
    }
}

이 문제에서 가장 중요한 벽 처리. 어쩌다 보니 다른 사람들보다 코드의 양이 많게 되었는데 이런 부분에서 미숙함이 묻어 나오는 듯합니다. 처음에는 HashMap을 2개만 만들어서 좌우/상하로 묶어서 좌표 값만 계산해서 처리하려고 했으나, 뒤에서 구현할 메서드들이 더 복잡해지는 겁니다. 그래서 각 방향에서 가지 못하는 인덱스를 저장할 HashMap 4개를 생성했습니다.

 

2-4. Heating

static void heating(){
    for(Heater heater : heaterList){
        int temperature = 5;
        int hx = heater.x, hy = heater.y, hd = heater.d;
        map[hx+dx[hd]][hy+dy[hd]] += temperature;
        Queue<Node> q = new ArrayDeque<>();
        q.add(new Node(hx+dx[hd], hy+dy[hd]));
        boolean[][] visited = new boolean[R][C];
        visited[hx+dx[hd]][hy+dy[hd]] = true;

        while(!q.isEmpty()){
            Node tmp = q.poll();
            if(hd == 1 || hd == 2){
                if(isRange(tmp.x, tmp.y+dy[hd])){
                    if(!visited[tmp.x][tmp.y+dy[hd]] && !isWall(tmp.x, tmp.y+dy[hd], hd)) {
                        visited[tmp.x][tmp.y+dy[hd]] = true;
                        if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                            map[tmp.x][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                            q.add(new Node(tmp.x, tmp.y + dy[hd]));
                        }
                    }
                }
                if(isRange(tmp.x-1, tmp.y+dy[hd])){
                    if(!visited[tmp.x-1][tmp.y+dy[hd]] && !isWall(tmp.x-1, tmp.y, 3) && !isWall(tmp.x-1, tmp.y+dy[hd], hd)){
                        visited[tmp.x-1][tmp.y+dy[hd]] = true;
                        if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                            map[tmp.x - 1][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                            q.add(new Node(tmp.x - 1, tmp.y + dy[hd]));
                        }
                    }
                }
                if(isRange(tmp.x+1, tmp.y+dy[hd])){
                    if(!visited[tmp.x+1][tmp.y+dy[hd]] && !isWall(tmp.x+1, tmp.y, 4) && !isWall(tmp.x+1, tmp.y+dy[hd], hd)){
                        visited[tmp.x+1][tmp.y+dy[hd]] = true;
                        if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                            map[tmp.x + 1][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                            q.add(new Node(tmp.x + 1, tmp.y + dy[hd]));
                        }
                    }
                }
            }
            else{
                if(isRange(tmp.x+dx[hd], tmp.y)){
                    if(!visited[tmp.x+dx[hd]][tmp.y] && !isWall(tmp.x+dx[hd], tmp.y, hd)) {
                        visited[tmp.x+dx[hd]][tmp.y] = true;
                        if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                            map[tmp.x + dx[hd]][tmp.y] += 4-Math.abs(hx-tmp.x+dx[hd]);
                            q.add(new Node(tmp.x + dx[hd], tmp.y));
                        }
                    }
                }
                if(isRange(tmp.x+dx[hd], tmp.y-1)){
                    if(!visited[tmp.x+dx[hd]][tmp.y-1] && !isWall(tmp.x, tmp.y-1, 2) && !isWall(tmp.x+dx[hd], tmp.y-1, hd)) {
                        visited[tmp.x+dx[hd]][tmp.y-1] = true;
                        if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                            map[tmp.x + dx[hd]][tmp.y - 1] += 4-Math.abs(hx-tmp.x+dx[hd]);
                            q.add(new Node(tmp.x + dx[hd], tmp.y - 1));
                        }
                    }
                }
                if(isRange(tmp.x+dx[hd], tmp.y+1)){
                    if(!visited[tmp.x+dx[hd]][tmp.y+1] && !isWall(tmp.x, tmp.y+1, 1) && !isWall(tmp.x+dx[hd], tmp.y+1, hd)) {
                        visited[tmp.x+dx[hd]][tmp.y+1] = true;
                        if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                            map[tmp.x + dx[hd]][tmp.y + 1] += 4-Math.abs(hx-tmp.x+dx[hd]);
                            q.add(new Node(tmp.x + dx[hd], tmp.y + 1));
                        }
                    }
                }
            }
        }
    }
}

Heater 리스트를 순회하면서 온풍기를 하나씩 켜줍니다. 온풍기의 바로 앞은 벽이 없다는 제약 조건으로 초기 값을 세팅하고, 큐를 만들어서 벽이 막혀있는지를 체크하면서 바람을 보내주었습니다. 바람을 보내는 것도 좀 까다로운데 일단은 한 칸에서 바람을 보낼 수 있는 방법은 총 3 가지고, 3곳 모두 바람을 불어넣을 수 있습니다.

예를 들자면, (x, y)에서 바람의 진행 방향이 오른쪽일 때, (x, y+1), (x-1, y+1), (x+1, y+1) 칸으로 바람을 보낼 수가 있습니다. 물론 바람은 대각선으로는 움직일 수 없고, 무조건 직각으로만 움직입니다. 바람이 이동하는 경로 중간에 벽이 존재한다면 목적지까지 바람이 닿을 수 없겠죠? 그래서 이 부분을 정리하기 위해 바람의 이동 경로를 생각해 봤습니다.

 

우좌상하 순이므로 순서대로 1, 2, 3, 4라 쳐봅시다.

우(1)
3 -> 1
1
4 -> 1

좌(2)
3 -> 2
2
4 -> 2

상(3)
2 -> 3
3
1 -> 3

하(4)
2 -> 4
4
1 -> 4

현재의 인덱스에서 다음 인덱스로 갈 때의 방향이 온풍기의 방향과 같을 때 목적지에 도착했다고 판단하면 됩니다. 어쨌든 이렇게 시각적으로 표현했을 때 방향이 겹치는 부분을 확인할 수 있습니다. 우, 좌 / 상, 하로 나눠서 적절히 처리하면 되겠죠?

 

예로 들자면,

if(isRange(tmp.x+dx[hd], tmp.y-1)){
    if(!visited[tmp.x+dx[hd]][tmp.y-1] && !isWall(tmp.x, tmp.y-1, 2) && !isWall(tmp.x+dx[hd], tmp.y-1, hd)) {
        visited[tmp.x+dx[hd]][tmp.y-1] = true;
        if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
            map[tmp.x + dx[hd]][tmp.y - 1] += 4-Math.abs(hx-tmp.x+dx[hd]);
            q.add(new Node(tmp.x + dx[hd], tmp.y - 1));
        }
    }
}

1) 다음 인덱스가 맵 범위 안에 있고 2) 바람이 분 칸이 아닐 경우 3) 그리고 가는 길 사이에 벽이 없을 경우를 고려하면 됩니다. 그리고 온풍기에서 멀어지면 멀어질수록 온도가 낮아지니까 이 부분도 포함해서 구현했습니다.

 

관련 메서드들 (isRange, isWall)

static boolean isRange(int x, int y){
    return 0 <= x && x < R && 0 <= y && y < C;
}
static boolean isWall(int x, int y, int d){
    HashSet<Integer> set;
    switch(d){
        case 1:
            if(rightBlock.containsKey(x)){
                set = rightBlock.get(x);
                if(set.contains(y)) return true;
            }
            break;
        case 2:
            if(leftBlock.containsKey(x)){
                set = leftBlock.get(x);
                if(set.contains(y)) return true;
            }
            break;
        case 3:
            if(upBlock.containsKey(x)){
                set = upBlock.get(x);
                if(set.contains(y)) return true;
            }
            break;
        case 4:
            if(downBlock.containsKey(x)){
                set = downBlock.get(x);
                if(set.contains(y)) return true;
            }
            break;
    }
    return false;
}

 

 

2-5. Control

static void control(){
    int[][] tmpArr = new int[R][C];
    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            for(int k = 1; k <= 4; k++){
                int nx = i + dx[k];
                int ny = j + dy[k];
                if(isRange(nx, ny) && !isWall(nx, ny, k)){
                    if(map[i][j] < map[nx][ny]){
                        tmpArr[i][j] += (map[nx][ny] - map[i][j])/4;
                        tmpArr[nx][ny] -= (map[nx][ny] - map[i][j])/4;
                    }
                }
            }
        }
    }
    for(int i = 0; i < R; i++)
        for(int j = 0; j < C; j++)
            map[i][j] += tmpArr[i][j];
}

자, 여기까지 왔으면 정말 별 거 없습니다. 필요한 메서드들은 앞에서 다 구현했거든요! 온도 조절 코드인 control 메서드는 따로 온도의 합과 차의 결과를 저장할 tmpArr를 추가로 생성합시다. 그런 후에 최종 온도 조절 결과를 원래의 배열에 더하면 됩니다!

 

2-6. Chilling

static void chilling(){
    for(int i = 0; i < R; i++)
        for(int j = 0; j < C; j++)
            if(i == 0 || i == R-1 || j == 0 || j == C-1)
                if(1 <= map[i][j]) map[i][j]-=1;
}

저는 사실 테두리 온도가 식는 부분을 어렵게 생각했거든요? 온도가 존재하는 칸의 테두리를 구해서 전부 -1 해주는 줄 알았는데, 문제를 다시 읽어보니 그냥 단순히 map의 가장 겉 테두리만 -1 해주는 문제였습니다. (그래서 좀 실망했었는데) 아무튼 날로 먹는 부분이니 단순하게 배열 순회로 -1 합시다.

 

2-7. Check

static boolean check(){
    for(Node tmp : checkList)
        if(map[tmp.x][tmp.y] < K) return false;
    return true;
}

이제 마지막으로 온도를 조사해야 할 칸을 순회합니다. Simulation에서 while문의 조건에 넣을 메서드라, boolean 값으로 return 해주면 되겠죠?

 

 

(2-8. Chocolate)

음, 별로 중요하지 않은 초콜릿은 나중에 드세요.


3. 소스 코드

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

public class BOJ23289 {
    static int R,C,K;
    static int[][] map;
    static class Node {
        int x, y;
        Node (int x, int y){
            this.x = x;
            this.y = y;
        }
    }

    static class Heater {
        int d, x, y;
        Heater (int d, int x, int y){
            this.d = d; this.x = x; this.y = y;
        }
    }

    static HashMap<Integer, HashSet<Integer>> downBlock = new HashMap<>();
    static HashMap<Integer, HashSet<Integer>> upBlock = new HashMap<>();
    static HashMap<Integer, HashSet<Integer>> leftBlock = new HashMap<>();
    static HashMap<Integer, HashSet<Integer>> rightBlock = new HashMap<>();
    static int[] dx = {0, 0, 0, -1, 1};
    static int[] dy = {0, 1, -1, 0, 0};
    static List<Node> checkList = new ArrayList<>();
    static List<Heater> heaterList = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken()); C = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        map = new int[R][C];
        for(int i = 0; i < R; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < C; j++){
                int tmp = Integer.parseInt(st.nextToken());
                switch(tmp){
                    case 1: case 2: case 3: case 4:
                        heaterList.add(new Heater(tmp, i, j));
                        break;
                    case 5:
                        checkList.add(new Node(i, j));
                        break;
                }
            }
        }
        int wallCnt = Integer.parseInt(br.readLine());
        for(int i = 0; i < wallCnt; i++){
            st = new StringTokenizer(br.readLine());
            int tx = Integer.parseInt(st.nextToken())-1;
            int ty = Integer.parseInt(st.nextToken())-1;
            int flag = Integer.parseInt(st.nextToken());
            HashSet<Integer> set, set2;
            switch (flag){
                case 0:
                    if(downBlock.containsKey(tx)){
                        set = downBlock.get(tx);
                        set.add(ty);
                        downBlock.put(tx, set);
                        set2 = upBlock.get(tx-1);
                        set2.add(ty);
                        upBlock.put(tx-1, set2);
                    }
                    else{
                        set = new HashSet<>();
                        set2 = new HashSet<>();
                        set.add(ty);
                        set2.add(ty);
                        downBlock.put(tx, set);
                        upBlock.put(tx-1, set2);
                    }
                    break;
                case 1:
                    if(leftBlock.containsKey(tx)){
                        set = leftBlock.get(tx);
                        set.add(ty);
                        leftBlock.put(tx, set);
                        set2 = rightBlock.get(tx);
                        set2.add(ty+1);
                        rightBlock.put(tx, set2);
                    }
                    else{
                        set = new HashSet<>();
                        set2 = new HashSet<>();
                        set.add(ty);
                        set2.add(ty+1);
                        leftBlock.put(tx, set);
                        rightBlock.put(tx, set2);
                    }
                    break;
            }
        }
        int chocolate = 0;
        while(!check()) {
            heating();
            control();
            chilling();
            chocolate++;
            if(100 < chocolate) break;
        }
        if(100 < chocolate) System.out.println(101);
        else System.out.println(chocolate);
    }

    static void heating(){
        for(Heater heater : heaterList){
            int temperature = 5;
            int hx = heater.x, hy = heater.y, hd = heater.d;
            map[hx+dx[hd]][hy+dy[hd]] += temperature;
            Queue<Node> q = new ArrayDeque<>();
            q.add(new Node(hx+dx[hd], hy+dy[hd]));
            boolean[][] visited = new boolean[R][C];
            visited[hx+dx[hd]][hy+dy[hd]] = true;

            while(!q.isEmpty()){
                Node tmp = q.poll();
                if(hd == 1 || hd == 2){
                    if(isRange(tmp.x, tmp.y+dy[hd])){
                        if(!visited[tmp.x][tmp.y+dy[hd]] && !isWall(tmp.x, tmp.y+dy[hd], hd)) {
                            visited[tmp.x][tmp.y+dy[hd]] = true;
                            if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                                map[tmp.x][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                                q.add(new Node(tmp.x, tmp.y + dy[hd]));
                            }
                        }
                    }
                    if(isRange(tmp.x-1, tmp.y+dy[hd])){
                        if(!visited[tmp.x-1][tmp.y+dy[hd]] && !isWall(tmp.x-1, tmp.y, 3) && !isWall(tmp.x-1, tmp.y+dy[hd], hd)){
                            visited[tmp.x-1][tmp.y+dy[hd]] = true;
                            if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                                map[tmp.x - 1][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                                q.add(new Node(tmp.x - 1, tmp.y + dy[hd]));
                            }
                        }
                    }
                    if(isRange(tmp.x+1, tmp.y+dy[hd])){
                        if(!visited[tmp.x+1][tmp.y+dy[hd]] && !isWall(tmp.x+1, tmp.y, 4) && !isWall(tmp.x+1, tmp.y+dy[hd], hd)){
                            visited[tmp.x+1][tmp.y+dy[hd]] = true;
                            if(0 < 4-Math.abs(hy-tmp.y+dy[hd])) {
                                map[tmp.x + 1][tmp.y + dy[hd]] += 4-Math.abs(hy-tmp.y+dy[hd]);
                                q.add(new Node(tmp.x + 1, tmp.y + dy[hd]));
                            }
                        }
                    }
                }
                else{
                    if(isRange(tmp.x+dx[hd], tmp.y)){
                        if(!visited[tmp.x+dx[hd]][tmp.y] && !isWall(tmp.x+dx[hd], tmp.y, hd)) {
                            visited[tmp.x+dx[hd]][tmp.y] = true;
                            if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                                map[tmp.x + dx[hd]][tmp.y] += 4-Math.abs(hx-tmp.x+dx[hd]);
                                q.add(new Node(tmp.x + dx[hd], tmp.y));
                            }
                        }
                    }
                    if(isRange(tmp.x+dx[hd], tmp.y-1)){
                        if(!visited[tmp.x+dx[hd]][tmp.y-1] && !isWall(tmp.x, tmp.y-1, 2) && !isWall(tmp.x+dx[hd], tmp.y-1, hd)) {
                            visited[tmp.x+dx[hd]][tmp.y-1] = true;
                            if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                                map[tmp.x + dx[hd]][tmp.y - 1] += 4-Math.abs(hx-tmp.x+dx[hd]);
                                q.add(new Node(tmp.x + dx[hd], tmp.y - 1));
                            }
                        }
                    }
                    if(isRange(tmp.x+dx[hd], tmp.y+1)){
                        if(!visited[tmp.x+dx[hd]][tmp.y+1] && !isWall(tmp.x, tmp.y+1, 1) && !isWall(tmp.x+dx[hd], tmp.y+1, hd)) {
                            visited[tmp.x+dx[hd]][tmp.y+1] = true;
                            if(0 < 4-Math.abs(hx-tmp.x+dx[hd])) {
                                map[tmp.x + dx[hd]][tmp.y + 1] += 4-Math.abs(hx-tmp.x+dx[hd]);
                                q.add(new Node(tmp.x + dx[hd], tmp.y + 1));
                            }
                        }
                    }
                }
            }
        }
    }

    static boolean isRange(int x, int y){
        return 0 <= x && x < R && 0 <= y && y < C;
    }

    static boolean isWall(int x, int y, int d){
        HashSet<Integer> set;
        switch(d){
            case 1:
                if(rightBlock.containsKey(x)){
                    set = rightBlock.get(x);
                    if(set.contains(y)) return true;
                }
                break;
            case 2:
                if(leftBlock.containsKey(x)){
                    set = leftBlock.get(x);
                    if(set.contains(y)) return true;
                }
                break;
            case 3:
                if(upBlock.containsKey(x)){
                    set = upBlock.get(x);
                    if(set.contains(y)) return true;
                }
                break;
            case 4:
                if(downBlock.containsKey(x)){
                    set = downBlock.get(x);
                    if(set.contains(y)) return true;
                }
                break;
        }
        return false;
    }

    static void control(){
        int[][] tmpArr = new int[R][C];
        for(int i = 0; i < R; i++){
            for(int j = 0; j < C; j++){
                for(int k = 1; k <= 4; k++){
                    int nx = i + dx[k];
                    int ny = j + dy[k];
                    if(isRange(nx, ny) && !isWall(nx, ny, k)){
                        if(map[i][j] < map[nx][ny]){
                            tmpArr[i][j] += (map[nx][ny] - map[i][j])/4;
                            tmpArr[nx][ny] -= (map[nx][ny] - map[i][j])/4;
                        }
                    }
                }
            }
        }
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++)
                map[i][j] += tmpArr[i][j];
    }

    static void chilling(){
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++)
                if(i == 0 || i == R-1 || j == 0 || j == C-1)
                    if(1 <= map[i][j]) map[i][j]-=1;
    }

    static boolean check(){
        for(Node tmp : checkList)
            if(map[tmp.x][tmp.y] < K) return false;
        return true;
    }
}

4. 한줄평

I pick myself up and get back in the race.

728x90

'etc. > BOJ' 카테고리의 다른 글

[BOJ] 9202 Boggle - Java  (0) 2024.12.10
[BOJ] 14942 개미 🐜 - Java  (1) 2024.12.08
[BOJ] 5373 큐빙 - Java  (0) 2024.08.09
[BOJ] 2293 동전 1 - Java  (0) 2023.06.06
[BOJ] 21609 상어 중학교 - Java  (0) 2023.03.24