[백준-골드4]미세먼지 안녕! - Java

iamjinseo·2023년 3월 1일
0

문제풀이-Java

목록 보기
33/53


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


문제

너무 길어서 안가져옴

풀이

package gold4;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

/*
 * 매커니즘
 * 1. 미세먼지 확산: 미세먼지가 있는 곳에서 '네 방향'으로 확산되나
 * 인접한 방향에 공청기가 있거나 칸이 없으면 확산 안됨
 * 또한 확산되는 양은 나누기 5이며 소수점은 버림. 확산시키고 남은 양은
 * => 그곳 미세먼지 - (미세먼지/5)*(확산된 방향 개수)

 * 2. 공청기 작동: 위쪽에서는 반시계 방향으로 바람이 순환하고 아래쪽에서는 시계방향으로 순환
 * 바람이 불면 미세먼지가 바람 방향대로 한 칸씩 이동
 * 공기청정기로 들어간 미세먼지는 사라짐.
 * */
public class B17144_미세먼지안녕 {
	static class Dust{ //원래 미세먼지가 있었던 곳의 정보만을 저장
		int r, c, value;

		public Dust(int r, int c, int value) {
			super();
			this.r = r;
			this.c = c;
			this.value = value;
		}
		
	}
	static int R, C, T;
	static int[][] map;
	static int[] di = { 1, -1, 0, 0 };
	static int[] dj = { 0, 0, 1, -1 };
	static int AP = -1; // 공기청정기 행 좦

	public static void main(String[] args) throws NumberFormatException, 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());
        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]==-1 && AP==-1) { // 공기청정기 좌표를 안넣은 경우에만 좌표넣음
					AP = i;
				}
			}
		} // end input
        for (int i = 0; i < T; i++) {
			diffuseDusts(); // 먼지확산
			
			runAP(); //공기청정기 가동
		}
        
        int res = 0;
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                if(map[i][j] == -1) 
                	continue;
                res += map[i][j];
            }
        }
        System.out.println(res);
    }

	// 모든 미세먼지를 확산
	static void diffuseDusts() {
		ArrayList<Dust>dusts = new ArrayList<Dust>(); 

		for (int i = 0; i < R; i++) {
			for (int j = 0; j < C; j++) {
				if (map[i][j] < 5) // 미세먼지가 5보다 작거나, 없거나, 공기청정기인 경우
					continue; // 확산 안됨
				dusts.add(new Dust(i, j, map[i][j])); //미세먼지 정보 저장
			}
		}
		for (Dust dust : dusts) {
			diffuse(dust);
		}
	}

	// 매개변수로 받은 dust 확산
	static void diffuse(Dust dust) {
		int value = dust.value / 5; // 확산될 먼지의 양
		int cnt=0; //확산 횟수\s
		System.out.println("현재 위치와 값:"+dust.r+" "+dust.c+": "+dust.value);
		System.out.println("확산시킬 양: "+value);
		for (int n = 0; n < 4; n++) {
			int ni = dust.r + di[n];
			int nj = dust.c + dj[n];

			// 범위검사
			if (ni < 0 || ni >= R || nj < 0 || nj >= C)
				continue;
			// 공기청정기 검사
			if(map[ni][nj]==-1)
				continue;

			map[ni][nj] += value; // 먼지를 확산시켰음
			System.out.println(ni+", "+nj+"에 확산시켰음. "+map[ni][nj]);
			cnt++;
		}
		map[dust.r][dust.c] -=  (value*cnt);
		System.out.println("value: "+value+", cnt: "+cnt);
		System.out.println("확산후 양: "+map[dust.r][dust.c]);
		for (int[] is : map) {
			System.out.println(Arrays.toString(is));
		}
	}

	// 공기청정기 가동
	static void runAP() {
		int top = AP; //공기청정기 윗부분
		int down = AP+1; //공기청정기 아랫부분
		
		// 위쪽 공기청정기에서 반시계방향 순환
		// 윗공기 아래로 
		for (int i = top-1; i > 0; i--) {
			map[i][0] = map[i-1][0];
		}
		// 오른쪽 공기 왼쪽으로
		for (int j = 0; j < C-1; j++) {
			map[0][j] = map[0][j+1];
		}
		// 아랫공기 위로
		for (int i = 0; i < top; i++) {
			map[i][C-1] = map[i+1][C-1];
		}
		// 왼쪽 공기 오른쪽으로
		for (int j = C-1; j > 1; j--) {
			map[top][j] = map[top][j-1];
		}
		// 공기청정기에서 -1이 날아왔으니 0으로 제거
		map[top][1] = 0;
		
		// 아래쪽 공기청정기에서 시계방향 순환
		// 아래에서 위로
		for (int i = down+1; i < R-1 ; i++) {
			map[i][0] = map[i+1][0];
		}
		// 오른쪽에서 왼쪽으로
		for (int j = 0; j < C-1; j++) {
			map[R-1][j] = map[R-1][j+1];
		}
		// 위에서 아래로
		for (int i = R-1; i > down; i--) {
			map[i][C-1] = map[i-1][C-1];
		}
		// 왼쪽에서 오른쪽으로
		for (int j = C-1; j > 1; j--) {
			map[down][j] = map[down][j-1];
		}
		map[down][1] = 0;
	}

}

멋있는 풀이법 없고 하라는대로 빡구현하면 됩니다!

결과

후기

처음에는 먼지들 있는 리스트 안만들고, diffuseDusts할 때마다 새로운 배열을 넣어서 확산결과를 넣으려 했음

근데 그 함수 안에서 먼지가 있는지 검사하고 diffuse를 실행하는 방식으로 하려다보니 확산된 먼지가 또 확산하는 사태 벌어짐..

결국 먼지들이 들어있는 리스트를 따로 만들기로 함

profile
일단 뭐라도 해보는 중

0개의 댓글