미세먼지 안녕! 은 내가 제일 어려워하는 구현 문제이다.
BFS, 다익스트르와 같은 문제는 문제 해결방식이 모두 비슷하고 공식이 존재하기에 문제 풀이에 어려움이 있더라도 정답을 도출 해 낼 수 있는데 이런 구현 문제는 문제 자체를 이애하는 데에도 시간이 걸려 많은 어려움을 느낀다.
이번에도 문제 이해를 잘못해 결국 답지를 찾아봐 이해를 해버렸다. 계산 설명부터 구현까지 너무 친절하고 상세히 설명해주신 탓에 많은 도움이 됐다.
노력 많이 해야 할 것 같다.
#include <iostream>
#include <deque>
#include <string>
#include <sstream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <map>
#include <cstring>
#include "Algorithm.h"
using namespace std;
int r, c, t;
int dust[50][50];
int compute[50][50] = { 0 };
vector<pair<int, int>> clean;
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
int non_clock[4] = { 1,-1,-1,1 };
int clock[4] = { 1,1,-1,-1 };
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
input();
solve();
return 0;
}
void solve() {
for (int i = 0; i < t; i++) {
spread_dust();
clean_dust();
}
}
void clean_dust() {
for (int i = 0; i < 2; i++) {
int x = clean[i].first;
int y = clean[i].second;
int nx, ny;
while (nx != x && ny != y) {
if (i == 0) {
}
}
}
}
void spread_dust() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
int count = 1;
if (dust[i][j] == -1) continue;
for (int z = 0; z < 4; z++) {
int nx = i + dx[z];
int ny = j + dy[z];
if (0 <= nx < r && 0 <= ny < c) {
compute[nx][ny] += (dust[i][j] / 5);
count++;
}
}
compute[i][j] += dust[i][j] - (dust[i][j] / 5 * count);
}
}
Duplicate();
}
void Duplicate()
{
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
dust[i][j] = compute[i][j];
}
}
}
void input()
{
cin >> r >> c >> t;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
int n;
cin >> n;
if (n == -1) {
clean.push_back(make_pair(i, j));
}
dust[i][j] = n;
}
}
}
#include <iostream>
using namespace std;
int r, c, t;
int room[51][51];
int add[51][51];
int dr[4] = {0, 1, 0, -1};
int dc[4] = {-1, 0, 1, 0};
int up_row, down_row; // 공기청정기 윗부분과 아랫부분의 행
int total_dust; // 총 먼지량
void input()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> r >> c >> t;
bool flag = false;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
cin >> room[i][j];
if (room[i][j] == -1)
{
if (!flag)
{
up_row = i;
flag = true;
}
else
down_row = i;
}
else
total_dust += room[i][j];
}
}
}
// 먼지의 확산 함수
void spreadDust()
{
// 미세먼지 확산량 계산
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
int cnt = 0;
int val = room[i][j] / 5;
if (room[i][j] == 0 || room[i][j] == -1)
continue;
for (int k = 0; k < 4; k++)
{
int nr = i + dr[k];
int nc = j + dc[k];
if (nr < 0 || nr >= r || nc < 0 || nc >= c)
continue;
if (room[nr][nc] == -1)
continue;
add[nr][nc] += val;
cnt++;
}
add[i][j] -= (cnt * val);
}
}
// 미세먼지 확산 업데이트
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
room[i][j] += add[i][j];
add[i][j] = 0;
}
}
}
// 공기청정기 순환에 의한 먼지 이동
void airCleaner()
{
// 사라지는 먼지 계산
total_dust -= room[up_row - 1][0];
total_dust -= room[down_row + 1][0];
// 위의 공기 순환 (반시계)
// 1. 왼쪽줄
for (int i = up_row - 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 <= up_row; i++)
room[i - 1][c - 1] = room[i][c - 1];
// 4. 아랫줄
for (int i = c - 1; i > 1; i--)
room[up_row][i] = room[up_row][i - 1];
room[up_row][1] = 0;
// 아래공기 순환 (시계)
// 1. 왼쪽줄
for (int i = down_row + 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 >= down_row; i--)
room[i][c - 1] = room[i - 1][c - 1];
// 4. 윗줄
for (int i = c - 1; i > 1; i--)
room[down_row][i] = room[down_row][i - 1];
room[down_row][1] = 0;
}
void solve()
{
while (t--)
{
// 미세먼지 확산
spreadDust();
// 공기순환에 의한 미세먼지 이동
airCleaner();
}
cout << total_dust << '\n';
}
int main()
{
input();
solve();
return 0;
}