본문 바로가기
알고리즘/프로그래머스

프로그래머스 LV2. 거리두기 확인하기 (자바)

by reumiii 2022. 3. 25.

🍀 문제

대기실은 5개이며, 각 대기실은 5x5 크기입니다.

거리두기를 위하여 응시자들 끼리는 맨해튼 거리1가 2 이하로 앉지 말아 주세요.

단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.

 

예를 들어,

 

위 그림처럼 자리 사이에 파티션이 존재한다면 맨해튼 거리가 2여도 거리두기를 지킨 것입니다.

 

위 그림처럼 파티션을 사이에 두고 앉은 경우도 거리두기를 지킨 것입니다.

 

위 그림처럼 자리 사이가 맨해튼 거리 2이고 사이에 빈 테이블이 있는 경우는 거리두기를 지키지 않은 것입니다.

 

 

자리에 앉아있는 응시자들의 정보와 대기실 구조를 대기실별로 담은 2차원 문자열 배열 places가 매개변수로 주어집니다. 각 대기실별로 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 배열에 담아 return 하도록 solution 함수를 완성해 주세요.

 

제한사항

  • places의 행 길이(대기실 개수) = 5
    • places의 각 행은 하나의 대기실 구조를 나타냅니다.
  • places의 열 길이(대기실 세로 길이) = 5
  • places의 원소는 P,O,X로 이루어진 문자열입니다.
    • places 원소의 길이(대기실 가로 길이) = 5
    • P는 응시자가 앉아있는 자리를 의미합니다.
    • O는 빈 테이블을 의미합니다.
    • X는 파티션을 의미합니다.
  • 입력으로 주어지는 5개 대기실의 크기는 모두 5x5 입니다.
  • return 값 형식
    • 1차원 정수 배열에 5개의 원소를 담아서 return 합니다.
    • places에 담겨 있는 5개 대기실의 순서대로, 거리두기 준수 여부를 차례대로 배열에 담습니다.
    • 각 대기실 별로 모든 응시자가 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 담습니다.

 

입출력 예

places result
[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] [1, 0, 1, 1, 1]

 

제한시간 안내

  • 정확성 테스트 : 10초
  1. 두 테이블 T1, T2가 행렬 (r1, c1), (r2, c2)에 각각 위치하고 있다면, T1, T2 사이의 맨해튼 거리는 |r1 - r2| + |c1 - c2| 입니다.

 

 

코딩테스트 연습 - 거리두기 확인하기

[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] [1, 0, 1, 1, 1]

programmers.co.kr

 

 

😊 나의 코드

class Solution {
    public int[] solution(String[][] places) {
        int[] answer = new int[places.length];
        for (int i = 0; i < places.length; i++) {// 대기실 한 개씩 확인
            answer[i] = 1;
            loop :
            for (int j = 0; j < places[0].length; j++) {// 대기실 row
                String p = places[i][j];
                for (int k = 0; k < 5; k++) {// 대기실 한 칸씩 확인
                    if (p.charAt(k) == 'P') {
                        if(!check(i, j, k, places)) {
                            answer[i] = 0;
                            break loop;
                        }
                    }
                }
            }
        }
        return answer;
    }

    public boolean check(int i, int j, int k, String[][] places) {
        String p = places[i][j];
        // 오른쪽 확인
        if (k+2 < 5) {
            if (p.charAt(k + 1) == 'P' || (p.charAt(k + 1) != 'X' && p.charAt(k + 2) == 'P')) {
                return false;
            }
        } else if (k+1 < 5) {
            if (p.charAt(k + 1) == 'P') {
                return false;
            }
        }

        //왼쪽 확인
        if (k-2 > 0) {
            if (p.charAt(k - 1) == 'P' || (p.charAt(k - 1) != 'X' && p.charAt(k - 2) == 'P')) {
                return false;
            }
        } else if (k-1 > 0) {
            if (p.charAt(k - 1) == 'P') {
                return false;
            }
        } 

        // 아래 확인
        if (j < 4) {
            String nextRow = places[i][j + 1];
            if (nextRow.charAt(k) == 'X') {
                // 대각선 오른쪽 아래           
                if (k < 4 && p.charAt(k + 1) != 'X' && nextRow.charAt(k + 1) == 'P') {
                    return false;
                }
                // 대각선 왼쪽 아래
                if (k > 1 && p.charAt(k - 1) != 'X' && nextRow.charAt(k - 1) == 'P') {
                    return false;
                }
            } else {
                if (nextRow.charAt(k) == 'P' || (j < 3 && places[i][j + 2].charAt(k) == 'P')) {
                    return false;
                }
                // 대각선 오른쪽 아래
                if (k+1 < 5 && nextRow.charAt(k + 1) == 'P') {
                    return false;
                }
                // 대각선 왼쪽 아래
                if (k-1 >= 0 && nextRow.charAt(k - 1) == 'P') {
                    return false;
                }
            }
        }

        return true;
    }
}

 

왼쪽위부터 자리를 확인하므로 상하좌우 다 확인할 필요없이

check 표시된 부분만 체크해서 거리두기를 지켰는지 확인했다.

 

 

댓글