PS

백준 17144번 미세먼지 안녕!

남마허 2020. 2. 7. 22:45

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

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다. 공기청정기는 항상 왼쪽 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼

www.acmicpc.net

 

 

 

 

<접근방법>

그냥 시뮬레이션 문제입니다.

다만 배열 돌리기를 구현해야하고 공기청정기가 깨끗한 공기를 내뱉고 미세먼지를 먹는다는 조건도

구현해주어야 합니다.

또한 미세먼지 번식은 동시에 이루어지기 때문에 임시 배열에 번식양을 저장해놨다가

한방에 더해야 합니다.

 

배열 돌리기 구현은 그냥 맵 복사 후에 방향 그대로 따라가며 구현하는게

가장 편한 방법인거 같습니다.

 

 

 


 

 

 

<코드>

#include <iostream>
#include <algorithm>
#include <memory.h>
using namespace std;

struct point {
	int y, x;
};

int n, m, T;
int map[50][50];
int tmap[50][50] = { 0, };
int dy[4] = { 1, -1, 0, 0 };//남북동서
int dx[4] = { 0, 0, 1, -1 };
int d_rc[4] = {2, 1, 3, 0};
int d_rrc[4] = {2, 0, 3, 1};
point a, b;

void print() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << map[i][j] << ' ';
		}
		puts("");
	}puts("");
}

void rrc() {
	int cmap[50][50];
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cmap[i][j] = map[i][j];
		}
	}

	int y = a.y;
	int x = a.x + 1;
	map[y][x] = 0;
	for (int i = 0; i < 4; i++) {
		while (1) {
			int ty = y + dy[d_rc[i]];
			int tx = x + dx[d_rc[i]];

			if (!(0 <= tx && tx < m && 0 <= ty && ty <= a.y)) break;
			if (map[ty][tx] == -1) break;

			map[ty][tx] = cmap[y][x];
			y = ty; x = tx;
		}
	}
}

void rc() {
	int cmap[50][50];
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cmap[i][j] = map[i][j];
		}
	}

	int y = b.y;
	int x = b.x + 1;
	map[y][x] = 0;
	for(int i=0; i<4; i++){
		while (1) {
			int ty = y + dy[d_rrc[i]];
			int tx = x + dx[d_rrc[i]];

			if (!(0 <= tx && tx < m && b.y <= ty && ty < n)) break;
			if (map[ty][tx] == -1) break;

			map[ty][tx] = cmap[y][x];
			y = ty; x = tx;
		}
	}
}

void spread(int y, int x) {
	int cnt = 0;
	int give = map[y][x] / 5;

	for (int i = 0; i < 4; i++) {
		int ty = y + dy[i];
		int tx = x + dx[i];

		if (ty < 0 || ty >= n || tx < 0 || tx >= m) continue;
		if (map[ty][tx] == -1) continue;

		tmap[ty][tx] += give;
		cnt++;
	}
	map[y][x] -= (give*cnt);
	if (map[y][x] < 0) map[y][x] = 0;
}

void simul() {
	while (T--) {
		memset(tmap, 0, sizeof(tmap));
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (map[i][j] != 0 && map[i][j] != -1) {
					spread(i, j);
				}
			}
		}

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				map[i][j] += tmap[i][j];
			}
		}
		rc();
		rrc();
	}
}

int cal() {
	int tres = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (map[i][j] == -1) continue;
			tres += map[i][j];
		}
	}
	return tres;
}

int main() {
	cin >> n >> m >> T;
	bool u = true;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> map[i][j];
			if (u && map[i][j] == -1) {
				u = false;
				a.y = i; a.x = j;
			}
			else if (!u && map[i][j] == -1) {
				b.y = i; b.x = j;
			}
		}
	}

	simul();

	cout << cal() << '\n';
	return 0;
}

 

 


 

 

<느낀 점>

-'동시에' 라는 개념을 구현할 때 유의할 것!

 

 

 

 

 

 

반응형