알고리즘/삼성

삼성 코딩테스트 기출_(백준)미세먼지 안녕!

twfnm67 2019. 9. 10. 22:54

난이도 ★☆☆

 

문제출처

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

 

17144번: 미세먼지 안녕!

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

www.acmicpc.net

포인트

1. 확장 함수와 정화 함수 만들기

전체적인 구조 : 확장, 정화 함수를 따로 구현해 놓은 후, main에서 T의 횟수만큼 확장과 정화를 호출하는 형태로 구현한다.

 

2. (확장 함수 구현 시) 배열의 범위 및 공기청정기 자리 유의하기

공기청정기가 있는 자리와 배열의 바운더리를 넘어가는 범위에는 미세먼지 확장이 이루어지지 않음에 유의한다.

 

3. (정화 함수 구현 시) 정화되는 방향에 맞추어, 공기청정기에 빨려 들어가는 칸부터 한 칸씩 당기는 방식으로 구현하기

공기청정기에 빨려 들어가는 칸부터 화살표 반대 방향으로 움직이며 한 칸씩 당겨주면 깔끔한 구현이 가능하다.

 

정답코드

#include <iostream>
#include <vector>
using namespace std;

int R, C, T;
int a[51][51];
int amount[51][51];
vector<int> airFresher;

int dx[4] = { 0,0,1,-1 };
int dy[4] = { -1,1,0,0 };

//확장 함수
void spread() {
	//각 칸마다, 얼만큼의 미세먼지가 확장될지 미리 계산하여 amount 배열에 저장해 둠
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			if (a[i][j] != -1) {
				amount[i][j] = a[i][j] / 5;
			}
		}
	}
	
    //실제 확장이 일어나는 부분
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			if (a[i][j] != -1) {
				int dir = 0;
				for (int k = 0; k < 4; k++) {
					int nx = i + dx[k];
					int ny = j + dy[k];
					if (a[nx][ny] != -1 && nx >= 0 && ny >= 0 && nx < R && ny < C) {
						dir++;
						a[nx][ny] += amount[i][j];
					}
				}
				a[i][j] -= (amount[i][j] * dir);
			}
		}
	}
}

//정화 함수
void fresh() {
	//윗 부분 정화
	for (int i = airFresher[0]; i > 0; i--) {
		a[i][0] = a[i - 1][0];
	}
	a[airFresher[0]][0] = 0;
	for (int i = 0; i < C - 1; i++) {
		a[0][i] = a[0][i + 1];
	}
	for (int i = 0; i < airFresher[0]; i++) {
		a[i][C - 1] = a[i + 1][C - 1];
	}
	for (int i = C - 1; i > 0; i--) {
		a[airFresher[0]][i] = a[airFresher[0]][i - 1];
	}

	//아래 부분 정화
	for (int i = airFresher[1]; i < R - 1; i++) {
		a[i][0] = a[i + 1][0];
	}
	a[airFresher[1]][0] = 0;
	for (int i = 0; i < C - 1; i++) {
		a[R - 1][i] = a[R - 1][i + 1];
	}
	for (int i = R - 1; i > airFresher[1]; i--) {
		a[i][C - 1] = a[i - 1][C - 1];
	}
	for (int i = C - 1; i > 0; i--) {
		a[airFresher[1]][i] = a[airFresher[1]][i - 1];
	}
	
}

int main() {
	cin >> R >> C >> T;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			cin >> a[i][j];
			if (a[i][j] == -1) {
				airFresher.push_back(i);
			}
		}
	}

	//T횟수만큼 확장과 정화 호출
	while (T--) {
		spread();
		fresh();
	}

	//남은 미세먼지 양 카운트
	int ans = 0;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			ans += a[i][j];
		}
	}
	cout << ans << '\n';
	return 0;
}