BOJ - 17144 미세먼지 안녕!

leehyunjon·2022년 5월 18일
0

Algorithm

목록 보기
36/162

17144 미세먼지 안녕! : https://www.acmicpc.net/problem/17144


Problem


Solve

미세먼지를 확산하는 함수와 공기청정기를 위,아래로 실행시켰을때 함수를 T번 반복 후 배열에 남아있는 미세먼지의 합을 반환하는 문제.

미세먼지를 확산하는 경우 각 미세먼지의 확산 누적값을 저장한 2차원 배열과 남은 미세먼지를 저장할 리스트를 이용해 모든 미세먼지의 확산값을 갱신한다.
확산값이 남아있는 미세먼지를 계산하는데 영향을 미치면 안되기 때문에 남은 미세먼지를 계산하고 누적값으로 미세먼지를 갱신해준다.

공기청정기를 실행하는 경우 공기청정기의 윗부분에서 x좌표가 C-1까지(➡), y좌표 0까지(⬆), x좌표 0까지(⬅), y좌표 공기청정기 위 위치까지(⬇)를 순환하며 미세먼지를 밀어낸다.
공기청정기의 아랫부분은 x좌표가 C-1까지(➡), y좌표 R-1까지(⬇), x좌표 0까지(⬅), y좌표 공기청정기 아래 위치까지(⬆)를 순환하며 미세먼지를 밀어낸다.


Code

public class 미세먼지안녕 {
	//행 길이
	static int R;
    //열 길이
	static int C;
    //시간
	static int T;
	static int[][] room;
	static int[] dy = {-1, 0, 1, 0};
	static int[] dx = {0, -1, 0, 1};
    //공기청정기 위치(0 : 위부분, 1 : 아랫부분)
	static int[][] machine;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		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());

		machine = new int[2][2];
		room = new int[R][C];

		boolean machineCheck = false;
		for (int r = 0; r < R; r++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int c = 0; c < C; c++) {
				room[r][c] = Integer.parseInt(st.nextToken());
                //공기청정기 위,아래 부분 초기화
				if (room[r][c] == -1) {
					if (!machineCheck) {
						machine[0][0] = r;
						machine[0][1] = c;
						machineCheck = true;
					} else {
						machine[1][0] = r;
						machine[1][1] = c;
					}
				}
			}
		}

		//T초 동안 미세번지 확산, 공기청정기 실행 반복
		while (T-- > 0) {
			spreadDust();
			cleanUp();
		}

		int answer = 0;
		for(int i=0;i<R;i++){
			for(int j=0;j<C;j++){
				if(room[i][j] != 0 && room[i][j] != -1){
					answer+=room[i][j];
				}
			}
		}

		bw.write(String.valueOf(answer));
		bw.flush();
		bw.close();
	}

	static void spreadDust() {
    	//확산 누적 값
		int[][] spreadDustSum = new int[R][C];
        //기존 미세먼지 리스트
		List<int[]> dustList = new ArrayList<>();
		for (int r = 0; r < R; r++) {
			for (int c = 0; c < C; c++) {

				if (room[r][c] != 0 && room[r][c] != -1) {
                	//확산 갯수
					int spreadCount = 0;
					for (int i = 0; i < 4; i++) {
						int ny = r + dy[i];
						int nx = c + dx[i];

						if (ny >= 0 && nx >= 0 && ny < R && nx < C && room[ny][nx] != -1) {
                        	//확산 누적
							spreadDustSum[ny][nx] += room[r][c] / 5;
							spreadCount++;
						}
					}
                    //기존의 미세먼지의 좌표 및 확산 갯수 저장
					dustList.add(new int[]{r,c,spreadCount});
				}
			}
		}

		//기존 미세먼지의 확산 후 남은 미세먼지 값을 먼저 갱신
		for(int[] d : dustList){
			int y = d[0];
			int x = d[1];
			int count = d[2];
			room[y][x] = room[y][x] - (room[y][x]/5)*count;
		}
        //확산 누적값 갱신
		for(int r=0;r<R;r++){
			for(int c=0;c<C;c++){
				room[r][c] += spreadDustSum[r][c];
			}
		}
	}


	static void cleanUp() {
		//공기청정기 위
		int[] upPosition = machine[0].clone();
		int prevDust = 0;
		int tmp = 0;
        //➡
		while(++upPosition[1] < C){
			tmp = room[upPosition[0]][upPosition[1]];
			room[upPosition[0]][upPosition[1]] = prevDust;
			prevDust = tmp;
		}
		upPosition[1]--;
        //⬆
		while(--upPosition[0] >= 0){
			tmp = room[upPosition[0]][upPosition[1]];
			room[upPosition[0]][upPosition[1]] = prevDust;
			prevDust = tmp;
		}
		upPosition[0]++;
        //⬅
		while(--upPosition[1] >= 0){
			tmp = room[upPosition[0]][upPosition[1]];
			room[upPosition[0]][upPosition[1]] = prevDust;
			prevDust = tmp;
		}
		upPosition[1]++;
        //⬇
		while(room[++upPosition[0]][upPosition[1]] != -1){
			tmp = room[upPosition[0]][upPosition[1]];
			room[upPosition[0]][upPosition[1]] = prevDust;
			prevDust = tmp;
		}

		int[] downPosition = machine[1].clone();
		//공기청정기 아래
		prevDust = 0;
		tmp = 0;
        //➡
		while(++downPosition[1] < C){
			tmp = room[downPosition[0]][downPosition[1]];
			room[downPosition[0]][downPosition[1]] = prevDust;
			prevDust = tmp;
		}
		downPosition[1]--;
        //⬇
		while(++downPosition[0] < R){
			tmp = room[downPosition[0]][downPosition[1]];
			room[downPosition[0]][downPosition[1]] = prevDust;
			prevDust = tmp;
		}
		downPosition[0]--;
        //⬅
		while(--downPosition[1] >= 0){
			tmp = room[downPosition[0]][downPosition[1]];
			room[downPosition[0]][downPosition[1]] = prevDust;
			prevDust = tmp;
		}
		downPosition[1]++;
        //⬆
		while(room[--downPosition[0]][downPosition[1]] != -1){
			tmp = room[downPosition[0]][downPosition[1]];
			room[downPosition[0]][downPosition[1]] = prevDust;
			prevDust = tmp;
		}
	}
}

Result


Reference

profile
내 꿈은 좋은 개발자

0개의 댓글