본문 바로가기
백준

[백준] code.plus(시뮬레이션과 구현,JAVA)17144번, 미세먼지 안녕!

by 열정적인 이찬형 2022. 8. 7.

문제 링크

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net


주의사항

  • JAVA를 사용하여 프로그램을 사용하였습니다.
  • 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{ 	
	public static void main(String[] args){
    }
}

문제 설명


접근 방법

 

이 문제에 핵심은

 

1. 미세먼지는 상하좌우 방향으로 확산이 진행됩니다.

2. 공기 청정기는 위, 아래가 존재하며 위는 반시계방향, 아래는 시계방향으로 끌어들인다.

3. 미세먼지가 공기 청정기에 들어가면 바로 정화됩니다.

4. T초가 지난 후 방에 존재하는 미세먼지에 양을 결과로 출력합니다.

 

알고리즘 진행 순서.

 

1. 입력되는 정보들을 저장합니다.

 

2. T초 동안 미세먼지 확산 및 공기 청정기 흡수를 진행합니다.

 

3. T초 이후에 방에 존재하는 미세먼지의 양을 결과로 출력합니다.

 

 

 

확산

 

미세먼지가 확산할 때에는 원래 양/5 크기로 상하좌우 방향으로 확산됩니다.

 

확산되었을 때 기준이 된 미세먼지의 양도 줄어듭니다.

0 0 0
0 15(기준 미세먼지) 0
0 0 0

기준 미세먼지의 양 / 5 = 15 / 5 = 3이 확산이 진행됩니다.

0 3 0
3 3(15 - 12) 3
0 3 0

 

흡수

 

공기 청정기에 위, 아래로 구분되며 위는 반시계, 아래는 시계방향으로 빨아들입니다.

공기의 흐름은 공기 청정기 기준으로 외곽으로 흐릅니다.

문제에서 설명된 내용을 확인하시면 이해하기 편하실 것입니다.

 

예제입력 2.

 

1. 입력되는 정보들을 저장합니다.

 

R : 7

C : 8

T : 2

0 0 0 0 0 0 0 9
0 0 0 0 3 0 0 8
-1 0 5 0 0 0 22 0
-1 8 0 0 0 0 0 0
0 0 0 0 0 10 43 0
0 0 5 0 15 0 0 0
0 0 40 0 0 0 20 0

 

 

2. T초 동안 미세먼지 확산 및 공기 청정기 흡수를 진행합니다.

 

1초.

확산!

 

0 0 0 0 0 0 1 8
0 0 1 0 3 0 5 6
-1 2 1 1 0 4 6 5
-1 5 2 0 0 2 12 0
0 1 1 0 5 10 13 8
0 1 9 4 3 5 12 0
0 8 17 8 3 4 8 4

 

흡수!

 

0 0 0 0 0 1 8 6
0 0 1 0 3 0 5 5
-1 0 2 1 1 0 4 6
-1 0 5 2 0 0 2 12
0 1 1 0 5 10 13 0
0 1 9 4 3 5 12 8
8 17 8 3 4 8 4 0

 

2초.

확산!

0 0 0 0 0 2 7 6
0 0 1 0 3 1 3 5
-1 0 3 1 1 0 6 6
-1 1 1 3 1 2 6 7
0 1 3 1 3 6 9 5
1 5 6 5 5 6 8 7
9 10 9 4 5 6 7 1

 

흡수!

0 0 0 0 2 7 6 5
0 0 1 0 3 1 3 6
-1 0 0 3 1 1 0 6
-1 0 1 1 3 1 2 6
1 1 3 1 3 6 9 7
9 5 6 5 5 6 8 5
10 9 4 5 6 7 1 7

3. T초 이후에 방에 존재하는 미세먼지의 양을 결과로 출력합니다.

 

살아남은 미세먼지의 양을 다 더한 값 188을 결과로 출력합니다.

 

  • BufferedReader를 사용하여 입력 값을 받았습니다.
  • StringTokenizer를 이용하여 입력된 정보에 대하여 나누었습니다.
  • T초 동안 diffusion,useCleaner를 순차적으로 실행하여 확산, 흡수에 대한 시뮬레이션을 진행합니다.
  • T초 이후 getDust를 실행하여 방의 미세먼지의 양을 BufferedWriter 저장하였습니다.
  • BufferedWriter에 저장된 결과값을 출력하였습니다.
  • diffusion함수는 미세먼지들이 확산을 진행합니다.
  • useCleaner함수는 위, 아래 공기 청정기가 흡수를 진행합니다.
  • getDust함수에서 방에 존재하는 모든 미세먼지의 양을 더합니다.
  • inRoom함수에서 이동하려는 칸이 방에 존재하는지 확인하는 함수입니다.

 

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

public class Main {
    static int R,C,T;
    static int[][] room;	//방에 미세먼지 양 저장하는 배열
    static int[][] dust;	//확산시 미세먼지 증감하는 양 저장 배열
    static int cleanerTop = -1, cleanerBottom;	//공기 청정기 위, 아래 위치 저장
    static int[] dx = {-1, 1, 0, 0};	//상하좌우 X변경값
    static int[] dy = {0, 0, -1, 1};	//상하좌우 Y변경값
    public static void main(String[] args) throws IOException {
        //입력값 처리하는 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //결과값 출력하는 BufferedWriter
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        room = new int[R][C];
        //공기 청정기 및 입력되는 미세먼지의 양 저장
        for(int i=0;i<R;i++){
            st = new StringTokenizer(br.readLine(), " ");
            for(int j=0;j<C;j++){
                room[i][j] = Integer.parseInt(st.nextToken());
                if(room[i][j] == -1 && cleanerTop==-1){
                    cleanerTop = i;
                    cleanerBottom = i+1;
                }
            }
        }
        //T초 동안 확산 및 흡수 진행
        for(int i=0;i<T;i++){
            dust = new int[R][C];
            //확산!
            for(int j=0;j<R;j++){
                for(int s=0;s<C;s++){
                    if(room[j][s] >= 5)	//5로 나누는 양이 확산되기 때문에 5보다 커야합니다.
                        diffusion(s, j);
                }
            }
            //확산된 먼지들 방에 합치기
            for(int j=0;j<R;j++){
                for(int s=0;s<C;s++)
                    room[j][s] += dust[j][s];
            }
            //흡수!
            useCleaner();
        }
        int answer = getDust()+2;	//T초후 모든 미세먼지의 양 합 구하기
        bw.write(answer + "");	//미세먼지의 양 BufferedWriter 저장
        bw.flush();	//결과 출력
        bw.close();
        br.close();
    }
    //확산 진행하는 함수
    static void diffusion(int x, int y){
        int value = room[y][x] / 5;
        //인접한 칸 탐색
        for(int i=0;i<4;i++){
            int tempX = x + dx[i];
            int tempY = y + dy[i];
            if(inRoom(tempX,tempY) && room[tempY][tempX] != -1){
               dust[tempY][tempX] += value;
               dust[y][x] -= value;
            }
        }
    }
    //흡수 진행하는 함수
    static void useCleaner(){
        //위쪽 공기 청정기 반시계 방향 진행
        int row = cleanerTop;
        for(int i=row-1;i>0;i--)
            room[i][0] = room[i-1][0];
        for(int i=0;i<C-1;i++)
            room[0][i] = room[0][i+1];
        for(int i=0;i<row;i++)
            room[i][C-1] = room[i+1][C-1];
        for(int i=C-1;i>1;i--)
            room[row][i] = room[row][i-1];
        room[row][1] = 0;

        //아래쪽 공기 청정기 시계 방향 진행
        row = cleanerBottom;
        for(int i=row+1;i<R-1;i++)
            room[i][0] = room[i+1][0];
        for(int i=0;i<C-1;i++)
            room[R-1][i] = room[R-1][i+1];
        for(int i=R-1;i>row;i--)
            room[i][C-1] = room[i-1][C-1];
        for(int i=C-1;i>1;i--)
            room[row][i] = room[row][i-1];
        room[row][1] = 0;
    }
    //방에 모든 미세먼지 양 구하는 함수
    static int getDust(){
        int sum = 0;
        for(int i=0;i<R;i++){
            for(int j=0;j<C;j++)
                sum += room[i][j];
        }
        return sum;
    }
    //이동하려는 칸이 방에 존재하는지 확인하는 함수
    static boolean inRoom(int x, int y){
        if(x>=0 && y>=0 && x<C && y<R)
            return true;
        return false;
    }

}
 
 
 

댓글