알고리즘/백준 문제 풀이

[BOJ] 17144. 미세먼지 안녕!

바켱서 2020. 7. 21. 22:14

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

접근 방법

문제에 나온 문항들에 대해서 그대로 구현해주면 된다.

  1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.
    • (r, c)에 있는 미세먼지는 인접한 네 방향으로 확산된다.
    • 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
    • 확산되는 양은 A/5이고 소수점은 버린다.
    • (r, c)에 남은 미세먼지의 양은 A - (A/5)×(확산된 방향의 개수) 이다.
  2. 공기청정기가 작동한다.
    • 공기청정기에서는 바람이 나온다.
    • 위쪽 공기청정기의 바람은 반시계방향으로 순환하고, 아래쪽 공기청정기의 바람은 시계방향으로 순환한다.
    • 바람이 불면 미세먼지가 바람의 방향대로 모두 한 칸씩 이동한다.
    • 공기청정기에서 부는 바람은 미세먼지가 없는 바람이고, 공기청정기로 들어간 미세먼지는 모두 정화된다.

주의 사항

  1. 동시에 미세먼지가 확산이 된다는 것을 잘 봐야한다.

Need Know

  1. 그냥 시뮬레이션..

전체 코드 ( Java )

import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;

class Main{
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static int R;
    static int C;
    static int T;
    static int ans = 2;
    static ArrayList<Location> airFilter;
    static int[][] map;
    static int[] dx = {-1,1,0,0};
    static int[] dy = {0,0,-1,1};
    public static void main(String[] args) throws IOException {
        set();
        solve();
        bw.flush();
        bw.close();
        br.close();
    }
    static void set() throws IOException {
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        map = new int[R][C];
        airFilter = new ArrayList<>();

        for(int i=0; i<R; i++){
            st = new StringTokenizer(br.readLine());
            for(int k=0; k<C;k++){
                map[i][k] = Integer.parseInt(st.nextToken());
                if(map[i][k]==-1) airFilter.add(new Location(i,k));
            }
        }
    }
    static void solve() throws IOException {
        for(int i=0; i<T; i++){
            // 미세먼지 확산
            int[][] temp = dustMoving();
            for(int z=0; z<R; z++){
                map[z] = temp[z].clone();
            }

            // 공기청정기 가동
            temp = airFilterRunning();
            for(int z=0; z<R; z++){
                map[z] = temp[z].clone();
            }
        }
        // 답구하기
        for(int i=0; i<R; i++){
            for(int k=0; k<C; k++){
                ans += map[i][k];
            }
        }
        bw.write(ans +"");
    }
    static int[][] dustMoving(){
        int[][] movingDust = new int[R][C];
        for(int i=0; i<R; i++){
            movingDust[i] = map[i].clone();
        }
        for(int i=0; i<R; i++){
            for(int k=0; k<C; k++){
                if(map[i][k] >= 5){
                    int thisDusting = map[i][k]/5;

                    int flagDusting = 0;
                    for(int z=0; z<4; z++){
                        int nx = i + dx[z];
                        int ny = k + dy[z];
                        if(nx>=R || ny >= C || nx<0 || ny <0 || map[nx][ny]==-1) continue;
                        movingDust[nx][ny] += thisDusting;
                        flagDusting ++;
                    }
                    movingDust[i][k] -= (thisDusting * flagDusting);
                }
            }
        }
        return movingDust;
    }
    static int[][] airFilterRunning() {
        int[][] movingDust = new int[R][C];
        for(int i=0; i<R; i++){
            movingDust[i] = map[i].clone();
        }
        // up move
        Location upLoc = airFilter.get(0);
        Location startLoc = new Location(airFilter.get(0).x, airFilter.get(0).y+1);
        int tempDust = 0;
        while (true){
            if(startLoc.x == upLoc.x && startLoc.y == upLoc.y) break;
            movingDust[startLoc.x][startLoc.y] = tempDust;
            tempDust = map[startLoc.x][startLoc.y];
            if(startLoc.x==upLoc.x && startLoc.y!=C-1){
                startLoc.y ++;
                continue;
            }
            if(startLoc.x==0 && startLoc.y!=0){
                startLoc.y--;
                continue;
            }
            if(startLoc.y==C-1 && startLoc.x!=0) {
                startLoc.x--;
                continue;
            }
            if(startLoc.y==0){
                startLoc.x++;
                continue;
            }
        }
        // down filter
        Location downLoc = airFilter.get(1);
        startLoc = new Location(airFilter.get(1).x, airFilter.get(1).y+1);
        tempDust = 0;
        while (true){
            if(startLoc.x == downLoc.x && startLoc.y == downLoc.y) break;
            movingDust[startLoc.x][startLoc.y] = tempDust;
            tempDust = map[startLoc.x][startLoc.y];
            if(startLoc.x==downLoc.x && startLoc.y!=C-1){
                startLoc.y ++;
                continue;
            }
            if(startLoc.x==R-1 && startLoc.y!=0){
                startLoc.y--;
                continue;
            }
            if(startLoc.y==C-1 && startLoc.x!=R-1) {
                startLoc.x++;
                continue;
            }
            if(startLoc.y==0){
                startLoc.x--;
                continue;
            }
        }
        return movingDust;
    }
}
class Location{
    int x,y;

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