길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm/Simulation

[백준 17144번] 미세먼지 안녕! (C/C++)

2022. 3. 30. 07:24

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
    'Algorithm/Simulation' 카테고리의 다른 글
    • [백준 17779번] 게리맨더링 2 (C/C++)
    • [백준 4991번] 로봇 청소기 (C/C++)
    • [백준 17143번] 낚시왕 (C/C+)
    • [백준 17140번] 이차원 배열과 연산 (C/C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바