홍시홍의 프로그래밍

[백준 17144] 미세먼지 안녕 본문

알고리즘 문제풀이/백준

[백준 17144] 미세먼지 안녕

홍시홍 2020. 2. 4. 22:42

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

 

17144번: 미세먼지 안녕!

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

www.acmicpc.net

요구사항

1. 미세먼지 확산 -> 공기 청정기 작동 t초 이후의 미세먼지 갯수 구하기

 

풀이

1. 미세먼지 확산시킨다

mapc -> map으로

2. 공기 청정기 작동시킨다

주어진 조건에 따라 돌리기

3. t초 후 미세먼지 갯수 구하기

 

#include <iostream>
#include <string.h>

using namespace std;

int map[101][101];
int mapc[101][101];
int n, m, k;
int sr1, sc1, sr2, sc2;
int ccc = 0;
int dr[4] = { -1,1,0,0 };
int dc[4] = { 0,0,-1,1 };
int ans = 0;
void dust() {
	//cout << "dust" << endl;
	memset(mapc,0, sizeof(map));
	mapc[sr1][sc1] = -1;
	mapc[sr2][sc2] = -1;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++) {
			if (map[i][j] > 0) {
				int count = 0;
				for (int k = 0; k < 4; k++) {
					int nr = i + dr[k];
					int nc = j + dc[k];
					
					if (nr < 0 || nc < 0 || nr >= n || nc >= m)
						continue;
					
					if (map[nr][nc] == -1) {
						continue;
					}
					count++;
				}
				int temp = map[i][j] - (map[i][j] / 5) * count;
				int num = (map[i][j] / 5);
				mapc[i][j] += temp;
				//map
				for (int k = 0; k < 4; k++) {
					int nr = i + dr[k];
					int nc = j + dc[k];

					if (nr < 0 || nc < 0 || nr >= n || nc >= m)
						continue;

					if (map[nr][nc] == -1) {
						continue;
					}
					mapc[nr][nc] += num;
				}

			}
		}
	}


}
int getupdir(int d) {
	if (d == 3) return 0;
	else if (d == 0) return 2;
	else if (d == 2) return 1;
}

int getdowndir(int d) {
	if (d == 3) return 1;
	else if (d == 1) return 2;
	else if (d == 2) return 0;
}
void blow() {
	//cout << "up" << endl;
	//위 바람
	int r = sr1;
	int c = sc1;
	int d = 3;
	int nr, nc;
	int tempnow = 0;
	int tempprev = 0;
	while (true) {
		nr = r + dr[d];
		nc = c + dc[d];
		if (mapc[nr][nc] == -1)
			break;
		if (nr < 0 || nc >= m || nc < 0 || nr >= sr2) {
			d = getupdir(d);
			nr = r + dr[d];
			nc = c + dc[d];
		}
		tempnow = mapc[nr][nc];
		mapc[nr][nc] = tempprev;
		tempprev = tempnow;
		r = nr;
		c = nc;
	}
	//위 바람
	//cout << "down" << endl;
	r = sr2;
	c = sc2;
	d = 3;
	tempnow = 0;
	tempprev = 0;
	int num = 0;
	while (true) {

		nr = r + dr[d];
		nc = c + dc[d];
		if (mapc[nr][nc] == -1)
			break;
		if (nr >= n  || nc >= m || nc < 0 || nr <= sr1) {
		//	cout << "c" << endl;
			d = getdowndir(d);
			nr = r + dr[d];
			nc = c + dc[d];
		}
	//	cout << nr << " " << nc << endl;
		tempnow = mapc[nr][nc];
		mapc[nr][nc] = tempprev;
		tempprev = tempnow;
		r = nr;
		c = nc;
	}
}
void solve() {
	int cnt = 0;
	while (true) {
		if (cnt == k) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					if (map[i][j] != -1) {
						ans += map[i][j];
					}
				}
			}
			return;
		}
		dust();
		blow();
		memcpy(map, mapc, sizeof(map));
		cnt++;
	}
}
int main() {
	cin >> n >> m >> k;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> map[i][j];
			if (ccc == 1 && map[i][j] == -1) {
				sr2 = i;
				sc2 = j;
			}
			if (ccc == 0 && map[i][j] == -1) {
				sr1 = i;
				sc1 = j;
				ccc++;
			}
		}
	}
	solve();
	cout << ans << endl;
}

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 14889] 스타트와 링크  (0) 2020.02.08
[백준 16235] 나무 재테크  (0) 2020.02.08
[백준 17140] 이차원 배열과 연산  (0) 2020.02.02
[백준 17142] 연구소 3  (0) 2020.02.02
[백준 14500] 테트로미노  (0) 2020.02.02
Comments