https://www.acmicpc.net/problem/17144
17144번: 미세먼지 안녕!
미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사
www.acmicpc.net
미세먼지 안녕!문제는 t번 미세먼지를 확산시키고, 공기청정기를 작동시켜 해결할 수 있습니다.
⚠️ 다만, 미세먼지의 확산이 모든 칸에서 동시에 발생하기 때문에, 확산시키는 것과, 확산된 양을 더해주는 것을 구분하여 진행해주어야 합니다.
또한, 공기청정기가 작동할 때, 그림에 나온 방향으로 진행하면서 한 칸씩 이동시키는 것이 아니라, 공기청정기부터 시작하여 한 칸씩 당겨주어야 합니다.
아래는 전체 코드입니다.
#include <bits/stdc++.h> using namespace std; #define x first #define y second int r, c, t; int board[50][50]; int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; void air(pair<int, int> a, int dir){ // a는 공기청정기 아래 칸의 좌표, f가 1이면 윗 바람, 0이면 아래 바람 pair<int, int> cur = a; // 공기청정기 위치 while(true){ pair<int, int> nx = {cur.x + dx[dir], cur.y + dy[dir]}; // 다음 칸이 방을 벗어나거나 공기청정기와 같은 행인 경우 방향을 바꿈 if(nx.x < 0 || nx.y < 0 || nx.x >= r || nx.y >= c || (cur.x == a.x && cur.y == c - 1)) { if(board[a.x - 1][a.y] == -1) dir = ((dir == 0) ? dir = 3 : dir - 1); else dir = (dir + 1) % 4; nx = {cur.x + dx[dir], cur.y + dy[dir]}; } // 다음 칸이 공기청정기라면, 현재 칸에 0을 채우고 종료 if(nx.x == a.x && nx.y == a.y) {board[cur.x][cur.y] = 0; break;} if(cur.x == a.x && cur.y == a.y){ // 현재 위치가 공기청정기라면 board[nx.x][nx.y] = 0; // 공기청정기로 들어간 미세먼지는 모두 정화된다 }else{ // 현재 위치가 공기청정기가 아니라면 board[cur.x][cur.y] = board[nx.x][nx.y]; // 한 칸씩 당김 } cur = nx; } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> r >> c >> t; pair<int, int> a; for(int i = 0; i < r; i++) for(int j = 0; j < c; j++){ cin >> board[i][j]; if(board[i][j] == -1) a = {i, j}; // 공기청정기의 위치 } int time = 0; while(time < t){ int temp[50][50]; fill(&temp[0][0], &temp[49][50], 0); for(int i = 0; i < r; i++){ // 미세먼지가 확산된다 for(int j = 0; j < c; j++){ if(board[i][j] > 0){ // 해당 칸에 미세먼지가 있는 경우 int n = 0; // 미세먼지가 확산된 방향의 개수 for(int dir = 0; dir < 4; dir++){ pair<int, int> nx = {i + dx[dir], j + dy[dir]}; if(nx.x < 0 || nx.y < 0 || nx.x >= r || nx.y >= c || board[nx.x][nx.y] == -1) continue; temp[nx.x][nx.y] += board[i][j] / 5; // 확산되는 양 n++; // 확산된 방향의 개수 } board[i][j] -= (board[i][j] / 5) * n; // (r,c)애 넘운 미세먼지의 양 } } } for(int i = 0; i < r; i++) for(int j = 0; j < c; j++) board[i][j]+=temp[i][j]; // 해당 칸으로 확산된 미세먼지의 양을 더해줌 // 공기청정기가 작동한다. air({a.x - 1, a.y}, 0); // 위쪽 공기청정기 바람 air(a, 2); // 아래쪽 공기청정기 바람 time++; // 시간 증가 } int ans = 0; for(int i = 0; i < r; i++) for(int j = 0; j < c; j++) if(board[i][j] != -1) ans += board[i][j]; cout << ans; }
아래는 문제 풀이에 사용된 테스트케이스입니다.
3 3 1 0 30 7 -1 10 0 -1 0 20 -> 55 4 5 1 1 2 3 4 5 -1 1 2 3 4 -1 4 5 6 7 2 3 4 5 6 -> 64
'Algorithm > Simulation' 카테고리의 다른 글
[백준 17779번] 게리맨더링 2 (C/C++) (0) | 2022.03.31 |
---|---|
[백준 4991번] 로봇 청소기 (C/C++) (0) | 2022.03.31 |
[백준 17143번] 낚시왕 (C/C+) (0) | 2022.03.30 |
[백준 17140번] 이차원 배열과 연산 (C/C++) (0) | 2022.03.29 |
[백준 16236번] 아기 상어 (C/C++) (0) | 2022.03.27 |