미세먼지 안녕!_17144

ddo_h·2020년 5월 19일
0
post-thumbnail

문제 출처 : 미세먼지안녕_17144

파라미터 정리

RxC 전체 맵 크기, r : row, c : col, (1,1)부터 시작함
Arc 각 칸에 있는 미세먼지 양
1번째 열에 공기청정기 있음, 공기 청정기는 2개의 행을 차지함 (Arc = -1)
윗행에 있는 공기청정기는 시계 반대 방향으로 순환
아랫행에 있는 공기청정기는 시계방향으로 순환
1초 동안 루틴{

  • 미세먼지 확산
    인접한 좌우상하에 확산됨
    확산되는 양은 Arc/5 (소수점은 버림)
    Arc = Arc - (Arc/5)x(확산된 방향의 개수)
    공기청정기 혹은 범위를 벗어난 곳은 확산X
  • 공기청정기 작동
    바람의 방향대로 미세먼지가 한칸씩 이동함
    from 공기청정기 : 0, to 공기청정기 : 삭제
    }
    원하는 것 = T초가 지난 후 방세 남아있는 미세먼지의 총 양을 반환

간략한 과정

input_1 R,C,T 입력받기 (6~R,C~50) (1~T~1000)
input_2 초기 맵 정보 Arc 입력받기
do{
Map 백업에 복사
인접한 곳 먼지 확산하기 (범위 벗어나는 곳, 공기청정기 부분X)
공기 순환하기 (순서가 방향이랑 반대로 되어야 함)
백업에 있는 정보 Map에 반영
윗 공기청정기 -> 반시계 방향으로 순환
아래 공기청정기 -> 시계 방향으로 순환
}while(T만큼 반복하도록)
공백(0), 공기청정기(-1) 제외하고 res에 더해주기
output res 출력하기

코드

#include <iostream>
#include <cstring>

using namespace std;

int R,C,T;
int Map[50][50];
int vent;
int backup[50][50];
int Dr[4] = {-1,1,0,0};
int Dc[4] = {0,0,-1,1};

void diffuse(int r, int c, int val){
    int nv = val/5;
    int cnt = 0;
    for(int i = 0; i < 4; i++){
        int nr = r + Dr[i], nc = c + Dc[i];
        if(backup[nr][nc] == -1) continue;
        if(nr < 0 || nc < 0 || nr > R-1 || nc > C-1) continue;
        cnt++;
        backup[nr][nc] += nv;
    }
    backup[r][c] -= nv*cnt;
    
    return;
}

int solve(){
    int res = 0;
    
    do{
        //먼지 확산하기
        memcpy(backup, Map, sizeof(Map));
        for(int i = 0; i < R; i++){
            for(int j = 0; j < C; j++){
                if(Map[i][j] > 0){
                    diffuse(i,j,Map[i][j]);
                }
            }
        }
        memcpy(Map, backup, sizeof(Map));
        //윗 공기 순환하기
        int start_p = vent;
        for(int i = start_p-1; i > 0; i--)
            Map[i][0] = Map[i-1][0];
        for(int j = 0; j < C-1; j++)
            Map[0][j] = Map[0][j+1];
        for(int k = 0; k < start_p; k++)
            Map[k][C-1] = Map[k+1][C-1];
        for(int t = C-1; t > 1; t--)
            Map[start_p][t] = Map[start_p][t-1];
        Map[start_p][1] = 0;
        //아랫 공기 순환하기
        start_p++;
        for(int i = start_p+1; i < R-1; i++)
            Map[i][0] = Map[i+1][0];
        for(int j = 0; j < C-1; j++)
            Map[R-1][j] = Map[R-1][j+1];
        for(int k = R-1; k > start_p; k--)
            Map[k][C-1] = Map[k-1][C-1];
        for(int t = C-1; t > 1; t--)
            Map[start_p][t] = Map[start_p][t-1];
        Map[start_p][1] = 0;
        //1초 지남
        T--;
    }while(T > 0);
    
    //먼지 개수 세기
    for(int i = 0; i < R; i++)
        for(int j = 0; j < C; j++)
            if(Map[i][j] > 0) res += Map[i][j];
            
    return res;
}

int main()
{
    cin >> R >> C >> T;
    for(int i = 0; i < R; i++)
        for(int j = 0; j < C; j++){
            cin >> Map[i][j];
            if(Map[i][j] == -1 && Map[i-1][j] == -1)
                vent = i-1;
        }

    cout << solve() << endl;

    return 0;
}
profile
열심히!

0개의 댓글