백준 17144 미세먼지 안녕!(Java,자바)

jonghyukLee·2021년 10월 18일
0

이번에 풀어본 문제는
백준 17144번 미세먼지 안녕! 입니다.

📕 문제 링크

❗️코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

class Dust
{
    int val,x,y;

    public Dust(int val, int x, int y)
    {
        this.val = val;
        this.x = x;
        this.y = y;
    }
}

public class Main {
    static int R,C,T,answer;
    static int air_x;
    static int [][] map;
    static List<Dust> dust;
    static int [] dx = {-1,1,0,0};
    static int [] dy = {0,0,-1,1};

    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());
        T = Integer.parseInt(st.nextToken());

        dust = new ArrayList<>();
        map = new int[R][C];

        for(int i = 0; i < R; ++i)
        {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < C; ++j)
            {
                map[i][j] = Integer.parseInt(st.nextToken());
                if(map[i][j] < 0) air_x = i;
            }
        }
        while(T-- > 0)
        {
            getDust();
            //확산
            for(Dust d : dust)
            {
                int spread_val = d.val / 5;
                int spread_cnt = 0;
                for(int dir = 0; dir < 4; ++dir)
                {
                    int mx = d.x + dx[dir];
                    int my = d.y + dy[dir];

                    if(!isValid(mx,my) || map[mx][my] < 0) continue;
                    map[mx][my] += spread_val;
                    spread_cnt++;
                }
                map[d.x][d.y] += d.val - (spread_val * spread_cnt);
            }
            dust.clear();
            //공기청정기
            clean(true);
            clean(false);
        }
        for(int [] i : map)
        {
            for(int j : i)
            {
                if(j > 0) answer+= j;
            }
        }
        System.out.print(answer);
    }
    static void clean(boolean flag)
    {
        if(flag) //위
        {
            map[air_x-2][0] = 0;
            for(int i = air_x-3; i >= 0; --i)
            {
                if(map[i][0] > 0)
                {
                    map[i+1][0] = map[i][0];
                    map[i][0] = 0;
                }
            }
            for(int i = 1; i < C; ++i)
            {
                if(map[0][i] > 0)
                {
                    map[0][i-1] = map[0][i];
                    map[0][i] = 0;
                }
            }
            for(int i = 1; i < air_x; ++i)
            {
                if(map[i][C-1] > 0)
                {
                    map[i-1][C-1] = map[i][C-1];
                    map[i][C-1] = 0;
                }
            }
            for(int i = C-2; i > 0; --i)
            {
                if(map[air_x-1][i] > 0)
                {
                    map[air_x-1][i+1] = map[air_x-1][i];
                    map[air_x-1][i] = 0;
                }
            }
        }
        else //아래
        {
            map[air_x+1][0] = 0;
            for(int i = air_x+2; i < R; ++i)
            {
                if(map[i][0] > 0)
                {
                    map[i-1][0] = map[i][0];
                    map[i][0] = 0;
                }
            }
            for(int i = 1; i < C; ++i)
            {
                if(map[R-1][i] > 0)
                {
                    map[R-1][i-1] = map[R-1][i];
                    map[R-1][i] = 0;
                }
            }
            for(int i = R-2; i >= air_x; --i)
            {
                if(map[i][C-1] > 0)
                {
                    map[i+1][C-1] = map[i][C-1];
                    map[i][C-1] = 0;
                }
            }
            for(int i = C-2; i > 0; --i)
            {
                if(map[air_x][i] > 0)
                {
                    map[air_x][i+1] = map[air_x][i];
                    map[air_x][i] = 0;
                }
            }
        }
    }
    static void getDust()
    {
        for(int i = 0; i < R; ++i)
        {
            for(int j = 0; j < C; ++j)
            {
                if(map[i][j] >= 5)
                {
                    dust.add(new Dust(map[i][j],i,j));
                    map[i][j] = 0;
                }
            }
        }
    }
    static boolean isValid(int x, int y)
    {
        return x >= 0 && y >= 0 && x < R && y < C;
    }
}

📝 풀이

매 초마다 미세먼지가 확산되고, 이후 공기청정기를 가동시켜 주어진 조건에 맞게 먼지를 순환시키는 문제입니다. 공기청정기에 들어간 먼지는 소멸됩니다.
먼저 현재 Map에서 값이 5이상, 즉 확산 가능한 미세먼지의 좌표를 리스트에 담아주는 getDust함수를 호출해줍니다. List를 탐색하며 각각의 먼지별로 확산을 진행해 준 후, clean함수를 두번 호출하여 공기청정기 상단, 하단 별로 공기를 순환시켜줍니다.
주어진 횟수(T)번 위의 과정을 반복해준 후 마지막으로 map에 남은 먼지들의 총합을 구해주면 해결할 수 있습니다.

📜 후기

문제의 조건이 길어 어렵게 느껴졌지만, 구현은 어렵지 않았던 문제였습니다.

profile
머무르지 않기!

0개의 댓글