출처 : https://www.acmicpc.net/problem/17144
풀이 방법
문제의 핵심
- 미세 먼지는 동시에 전파된다.
- 임시 배열을 사용해서 한 번에 업데이트하면 된다.
- 임시 배열을 로컬 변수로 선언했다.
- 로컬 배열은 항상 memset으로 초기화 해야한다.
- 공기 청정기의 미세먼지 밀어내기 구현
- 코너 부분에서 간단하게 구현하기 위해 밀어내기를 구현하는 순서가 중요하다.
- 윗부분 같은 경우 왼쪽, 밑, 오른쪽, 위 쪽 순서로 밀어낸다면 코너 부분에 크게 신경 쓰지 않아도 된다.
- 공기 청정기 위 아래 구하기
- 두 입력을 받고 정렬을 통해 위 아래 구분이 가능하다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
int R, C, T;
int room[51][51];
vector<int> machine;
int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};
void air_clear() {
//위쪽 반시계 방향
//왼, //위, //오, //밑
// 1. 왼쪽줄
for (int i = machine[0]-1;i > 0;i--) {
room[i][0] = room[i-1][0];
}
// 2. 위쪽줄
for (int i = 0;i < C-1; i++) {
room[0][i] = room[0][i+1];
}
// 3. 오른쪽줄
for (int i = 1;i <= machine[0];i++) {
room[i-1][C-1] = room[i][C-1];
}
// 4.아랫줄
for (int i = C-1;i > 1;i--) {
room[machine[0]][i] = room[machine[0]][i-1];
}
room[machine[0]][1] = 0;
//아래쪽 시계 방향
//왼, // 밑, //오, // 위
// 아래공기 순환 (시계)
// 1. 왼쪽줄
for (int i = machine[1] + 1; i < R - 1; i++)
room[i][0] = room[i + 1][0];
// 2. 아랫줄
for (int i = 0; i < C - 1; i++)
room[R - 1][i] = room[R - 1][i + 1];
// 3. 오른쪽줄
for (int i = R - 1; i >= machine[1]; i--)
room[i][C - 1] = room[i - 1][C - 1];
// 4. 윗줄
for (int i = C - 1; i > 1; i--)
room[machine[1]][i] = room[machine[1]][i - 1];
room[machine[1]][1] = 0;
}
void spread() {
int temp[51][51]; //전파를 위한 임시 배열
memset(temp, 0, sizeof(temp));
for (int i = 0;i < R;i++) {
for (int j = 0;j < C;j++) {
if (room[i][j] < 1) continue; // 비었거나, 청정기일 때 패스하기
int cnt = 0, val = room[i][j] / 5; // 전파 값
for (int k = 0;k < 4;k++) { // 동서남북 전파하기
int ny = i + dy[k];
int nx = j + dx[k];
if (ny >= 0 && ny < R && nx >= 0 && nx < C) {
if (room[ny][nx] != -1) {
temp[ny][nx] += val;
cnt++;
}
}
}
temp[i][j] -= (val * cnt); // 전파 횟수만큼 빼주기
}
}
for (int i = 0;i < R;i++) { // 전파 결과 업데이트
for (int j = 0;j < C;j++) {
room[i][j] += temp[i][j];
temp[i][j] = 0;
}
}
}
int main() {
cin >> R >> C >> T;
for (int i = 0;i < R;i++) { // 방 입력 받기
for (int j = 0;j < C;j++) {
cin >> room[i][j];
if (room[i][j] == -1) { // 청정기이면 벡터에 저장
machine.push_back(i);
}
}
}
sort(machine.begin(), machine.end()); // 정렬을 통해 청정기의 위아래 구분
for (int i = 0;i < T;i++) { // T초 통안 저파
spread();
air_clear();
}
int ans = 0;
for (int i = 0;i < R;i++) { // T초 후 미세먼지 카운트
for (int j = 0; j < C;j++) {
if (room[i][j] > 0) {
ans += room[i][j];
}
}
}
cout << ans << endl;
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준] 상어 초등학교 21608번 (c++) 구현, 우선순위 큐 정렬 (0) | 2024.10.10 |
---|---|
[백준] 선 긋기 2170번 (C++) 라인스와핑 (1) | 2024.10.10 |
[백준] 수 묶기 1744번 (c++) 그리디, 수를 잘 나누기 (0) | 2024.10.02 |
[백준] 경사로 14890 (c++) 구현 (0) | 2024.10.02 |
[백준] 퇴사 2 15486번 (c++) dp 최댓값으로 갱신하기 (1) | 2024.10.01 |