개발새발 로그

[JS] 백준 17144번 : 미세먼지 안녕! 본문

알고리즘

[JS] 백준 17144번 : 미세먼지 안녕!

이즈흐 2023. 7. 9. 15:22

https://www.acmicpc.net/problem/17144

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net

 

 

 

📋풀이방법

1. 공기청정기좌표를 구한다

2. T횟수만큼 반복한다.

3.현재 미세먼지들의 좌표를 추출한다.

4. 복사배열 temp를 생성하고 0으로 초기화해준다.

  -복사배열에 공기청정기 위치를 넣어준다.

5. 미세먼지좌표들을 이용해 미세먼지를 확산한다.

  - 좌표에 -1이거나 벽 바깥쪽이 아니면 확산 가능

  -이때 먼저 확산가능한 횟수를 저장하고, 미세먼지 하나의 확산가능한 좌표를 배열에 저장한다.

  -미세먼지 확산될 때의 수와 확산된 후의 숙주 미세먼지의 값을 구해놓는다.

  -복사배열에 숙주 미세먼지의 좌표에 확산후 숙주 미세먼지의 값을 누적한다.

  -확산가능한 좌표에 저장한 좌표들을 이용해서 그 좌표에 확산될 때의 수를 누적한다.

6. 즉 원본배열의 숙주 미세먼지들의 값을 이용해서 복사 배열에 누적해서 넣으면 값이 꼬이지 않는다.

7. 다시 원본배열에 복사배열을 보사한다.

 

8. 공기청정기 바람으로순환한다.

9. 공기청정기 바람 순환은 아래와 같이 진행한다.

10. 공기청정기의 마지막 부분에서 부터 뒤의 숫자를 앞에 넣으면서 4번의 반복을한다.

 

🤟내 제출

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim();
input=input.replace(/\r/g,"").split("\n");

let [N,M,T]=input.shift().split(" ").map(Number);
let arr=[]
for(var i=0;i<N;i++){
    arr.push(input.shift().split(" ").map(Number));
}
let dy=[1,0,0,-1];
let dx=[0,1,-1,0];
let count=0;
let topAir=[];
let botAir=[];

// 위쪽 공기청정기 순환 (반시계방향)
function rotateUp(airY) {
    //마지막 공기청정기 열부분 0,0 -> 1,0
    for (let row = airY - 2; row >= 0; row--) {
        arr[row + 1][0] = arr[row][0]; 
    }
    //세번째 공기청정기 순환부분 0,0 <- 0,1  0,1 <- 0,2 ...
    for (let col = 1; col < M; col++) {
        arr[0][col - 1] = arr[0][col];
    }
    //두번째 공기청정기 순환부분  0,7 <- 1,7  1,7 <- 2,7 ...
    for (let row = 1; row <= airY; row++) {
        arr[row - 1][M - 1] = arr[row][M - 1];
    }
    //첫번째 공기청정기 순환부분 2,6 <- 2,5 2,5 <- 2,4 ...
    for (let col = M - 2; col > 0; col--) {
        arr[airY][col + 1] = arr[airY][col];
    }
    //공기청정이 바로 앞 부분은 0으로
    arr[airY][1] = 0;
}

// 아래쪽 공기청정기 순환 (시계방향)
function rotateDown(airY) {
    //마지막 공기청정기 순환부분 4,0 <- 5,0  5,0 <- 6,0
    for (let row = airY + 2; row < N; row++) {
        arr[row - 1][0] = arr[row][0];
    }

    for (let col = 1; col < M; col++) {
        arr[N - 1][col - 1] = arr[N - 1][col];
    }

    for (let row = N - 2; row >= airY; row--) {
        arr[row + 1][M - 1] = arr[row][M - 1];
    }

    for (let col = M - 2; col > 0; col--) {
        arr[airY][col + 1] = arr[airY][col];
    }

    arr[airY][1] = 0;
}

let flag=false
for(var i=0;i<N;i++){
    for(var j=0;j<M;j++){
        if(arr[i][j]==-1) {
            topAir=[i,j];
            botAir=[i+1,j];
            flag = true;
            break;
        }
    }
    if (flag) break;
}

while(count!=T){
    let mi=[];
    let air=[];
    //미세먼지 좌표추출
    for(var i=0;i<N;i++){
        for(var j=0;j<M;j++){
            if(arr[i][j]!=-1 && arr[i][j]!=0){
                mi.push([i,j]);
            }
        }
    }
    let temp=Array.from({length:N},()=>Array(M).fill(0))
    //복사배열에 공기청정기 위치 넣기
    temp[topAir[0]][topAir[1]] = -1;
    temp[botAir[0]][botAir[1]] = -1;
    //미세먼지 확산
    for(var i=0;i<mi.length;i++){
        let [y,x]=mi[i];
        let cnt=0;
        let go=[]
        for(var j=0;j<4;j++){
            let nx=x+dx[j];
            let ny=y+dy[j];
            
            if(nx>=0 && ny>=0&& nx<M && ny<N&& arr[ny][nx]!=-1){
                cnt++;
                go.push([ny,nx])
            }
        }
        let na=Math.floor(arr[y][x]/5);
        let nb=arr[y][x]-na*cnt
        

        temp[y][x]+=nb;
        go.forEach((gox)=>{
            let [ty,tx]=gox;
            temp[ty][tx]+=na;      
        })
        
        
    }
    //원본배열에 복사배열을 다시 복사
    arr=temp.map(o=>[...o])
    //공기청정기 바람 순환
    rotateUp(topAir[0]);
    rotateDown(botAir[0]);
    count++;
}
let answer=0;
//모든 먼지 수 더하기
for (let row = 0; row < N; row++) {
    for (let col = 0; col < M; col++) {
        if (arr[row][col] > 0) answer += arr[row][col];
    }
}
console.log(answer);

 

 

 

 

💢어려웠던 점

1. 미세먼지 확산부분은 쉬웠지만 공기청정기 바람으로 배열의 회전하는 부분이 어려웠다

 -원래는 큐에 그 숫자들을 넣고 맨앞의 숫자를 맨 뒤에 push만하면 되는데 그걸 다시 배열에 정확한 좌표에 넣어야하는 것이였으므로 이 방법은 사용하지 못했다.

-마지막 부터 뒤의 좌표의 숫자를 앞의 좌표에 덮어씌우면서 순환해야했다.

 

 

728x90
반응형
LIST

'알고리즘' 카테고리의 다른 글

[JS] 백준 2363 : 치즈  (0) 2023.07.11
[JS]백준 14890 : 경사로  (0) 2023.07.10
[JS] 백준 15683 : 감시  (0) 2023.07.08
[JS] 백준 2573 : 빙산  (0) 2023.07.07
[JS] 백준 14891 : 톱니바퀴  (0) 2023.07.06