[프로그래머스/JS] 거리두기 확인하기

코린·2023년 11월 14일
0

알고리즘

목록 보기
43/44
post-thumbnail

🧐 문제 풀이

조건들에 맞춰서 구현해주면 되는 문제입니다~~

  1. 거리두기를 위하여 응시자들 끼리는 맨해튼 거리1가 2 이하로 앉지 말아 주세요.
  2. 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.

거리두기를 위반하는 상황들

  1. 자신을 기준으로 상하좌우에 사람이 존재하는 경우

  2. 자신을 기준으로 상하좌우가 빈 공간이면서 맨해튼 거리2인 곳에 사람이 존재하는 경우

이 경우는 좌측일 경우에는 좌측 맨해튼 거리 2인 경우만 보면 됩니다.

현재 좌표를 (x,y) 라고 하면 좌측이동 좌표는 (x-1,y) 겠죠?
그럼 우리는 (x-2,y)에 사람이 존재하는지만 봐주면 되는겁니다욧!

//빈공간 너머에 사람있는지 확인    
let check_x = nx-x;
let check_y = ny-y;
                        
if(nx+check_x >= 0 && ny+check_y >= 0 && 
   nx+check_x < N && ny+check_y < N)
{
   if(map[ny+check_y][nx+check_x]==="P")return 0;
}

위 처럼 현재좌표와 다음좌표의 차이를 구해서 이를 더해서 맨해튼 거리가 2인 곳까지 확인해 주었습니다.

  1. 대각선에 사람이 존재하면서 파티션이 없는 경우

이 경우도 위의 경우와 비슷합니다!

다른점이라고 한다면 위 그림처럼 두 점을 봐줘야 한다는 것이죵!

//대각선 체크   
let check_x = x-nx;
let check_y = y-ny;
                        
if(nx+check_x >= 0 && ny+check_y >= 0 && 
   nx+check_x < N && ny+check_y < N)
{
   if(map[ny][nx+check_x]==="O" || map[ny+check_y][nx]==="O") return 0;
}

여기서의 차이는 현재좌표에서 다음이동좌표를 빼주어야 합니다!
역으로 이동해야 하기 때문입니다!

이전의 경우는 원래 가던 방향으로 이동하기 때문에 다음이동좌표에서 현재좌표를 빼주었습니다!

📝 결과 코드

function solution(places) {
    var answer = [];
    
    //상 하 우 좌 우하 우상 좌하 좌상
    let dx = [0,0,1,-1,1,1,-1,-1];
    let dy = [1,-1,0,0,1,-1,1,-1];
    let N;
    
    function check(map,x,y){
        
        //상하좌우 살피기
        for(let d=0;d<4;d++){
            
            let nx = x+dx[d];
            let ny = y+dy[d];
            
            //범위를 벗어나는 경우
            if(nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
            
            //사람이 있는 경우 지켜지지 않으므로 0 return
            if(map[ny][nx]==="P") return 0;
  
            //빈 공간인 경우
            if(map[ny][nx]==="O"){

                //빈공간 너머에 사람있는지 확인    
                let check_x = nx-x;
                let check_y = ny-y;
                        
                if(nx+check_x >= 0 && ny+check_y >= 0 && nx+check_x < N && ny+check_y < N){
                        if(map[ny+check_y][nx+check_x]==="P")return 0;
             
            }
                
                
            }
            
        }
        
        //대각선에 사람있나 확인
                for(let d3=3;d3<8;d3++){
                    let nx = x+dx[d3];
                    let ny = y+dy[d3];
                    
                    //범위를 벗어나는 경우
                    if(nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
                                      
                    if(map[ny][nx]==="P"){
                        
                        let check_x = x-nx;
                        let check_y = y-ny;
                        if(nx+check_x >= 0 && ny+check_y >= 0 && nx+check_x < N && ny+check_y < N){
                        //대각선이면 x,y 사이에 접해있는 곳에 사람이 있나 확인해야함
                        if(map[ny][nx+check_x]==="O" || map[ny+check_y][nx]==="O"){
                        return 0;
                        }
                    }
                        
                    }
            }
            
            return 1;
        
    }
    
    for(let tc=0;tc<places.length;tc++){
        
        let queue=[];
        N = places[tc].length;
        
        for(let y=0;y<N;y++){
            for(let x=0;x<N;x++){
                if(places[tc][y][x]==="P") queue.push([x,y]);    
            }
        }
        
        let res = 1;
        for(let i=0;i<queue.length;i++){
            
            if(check(places[tc],queue[i][0],queue[i][1])===0){
                res=0;
                break;
            }
           
        }

         answer.push(res);
        
    }
    
    return answer;
}
profile
안녕하세요 코린입니다!

0개의 댓글