https://programmers.co.kr/learn/courses/30/lessons/81302?language=java
코딩테스트 연습 - 거리두기 확인하기
[["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
문제 설명
개발자를 희망하는 죠르디가 카카오에 면접을 보러 왔습니다.
코로나 바이러스 감염 예방을 위해 응시자들은 거리를 둬서 대기를 해야하는데 개발 직군 면접인 만큼
아래와 같은 규칙으로 대기실에 거리를 두고 앉도록 안내하고 있습니다.
- 대기실은 5개이며, 각 대기실은 5x5 크기입니다.
- 거리두기를 위하여 응시자들 끼리는 맨해튼 거리1가 2 이하로 앉지 말아 주세요.
- 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.
예를 들어,
위 그림처럼 자리 사이에 파티션이 존재한다면 맨해튼 거리가 2여도 거리두기를 지킨 것입니다. | 위 그림처럼 파티션을 사이에 두고 앉은 경우도 거리두기를 지킨 것입니다. | 위 그림처럼 자리 사이가 맨해튼 거리 2이고 사이에 빈 테이블이 있는 경우는 거리두기를 지키지 않은 것입니다. |
응시자가 앉아있는 자리(P)를 의미합니다. | 빈 테이블(O)을 의미합니다. | 파티션(X)을 의미합니다. |
5개의 대기실을 본 죠르디는 각 대기실에서 응시자들이 거리두기를 잘 기키고 있는지 알고 싶어졌습니다. 자리에 앉아있는 응시자들의 정보와 대기실 구조를 대기실별로 담은 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을 담습니다.
입출력 예
placesresult
[["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] |
풀이코드
class Solution {
public int[] solution(String[][] places) {
int[] answer = new int[] {1,1,1,1,1};
char[][] room = new char[5][5];
int[]di = new int[] {-1,1,0,0};//상하좌우
int[]dj = new int[] {0,0,-1,1};
for(int W=0; W<5; W++) {//대기실
for(int i = 0; i< 5; i++) {
room[i] = places[W][i].toCharArray();
}
loop:
for(int i = 0; i< 5; i++) {
for(int j = 0; j< 5; j++) {//한칸씩 돌면서
if(room[i][j]=='P') {//사람이 있으면,
//유클리드 거리 1
for(int d= 0; d<4; d++) {
int x = i+di[d],y = j+dj[d];
if(x>=0&&y>=0&&x<5&&y<5) {
if(room[x][y]=='P') {
answer[W]=0;
break loop;
}else if(room[x][y]=='O') {
for(int dd = 0; dd<4; dd++) {
int xx = x+di[dd],yy=y+dj[dd];
if(xx==i && yy==j)continue;
if(xx>=0&& yy>=0 &&xx<5&&yy<5 && room[xx][yy]=='P') {
answer[W]=0;
break loop;
}
}
}
}
}
}
}
}
}
return answer;
}
}
좀 번거롭게 해결했다. 우선 0인줄 알았어서 틀렸는데 O였다...
놀랍게 이것만 틀리면 테스트3,5,8,11,13,16 만 틀려서 79.1 이 나와서 진짜 뭐가 틀렸지 하고 고민하게 된다.
먼저 이 값들은 정해진 경우의 수가 많아서 시간에 신경을 덜 쓰고 풀 수 있었다.
먼저 기본 값들을 세팅해준다. answer에 기본 1을 적어두고 거리두기를 못지켰을 경우, 0으로 바꾸는 알고리즘을 이용한다. 따라서 1로 answer을 초기화해둔다.
그리고 한 대기실 안의 크기는 모두 같으니까 room을 char[5][5]로 선언해준다.
그리고 유클리드 거리를 구하기 위해서 상하좌우를 이동할 수 있는 di, dj를 선언해준다.
그리고 5개의 대기실을 돌면서 검사하기위해서, W를 대기실 번호라고 생각하고,
현재 검사할 room에 char로 변환해서, 방의 배치를 넣는다.
그리고 한 칸 씩 돌면서, 'P'사람이 나오면 그 값의 상하좌우 유클리드 2 거리를 검사해서 결과가 나오게한다.
상하좌우를 검사하기 위해서 di와 dj를 반복하면서 x와 y를 선언해준다.
상하좌우 움직인 값이 대기실의 범위를 벗어나지 않는다면, 유클리드 1거리에 'P'사람이 있다면, 그대로 answer[W]를 0으로 바꾸고, 대기실의 반복문을 벗어난다.
유클리드 1의 거리에 'P'가 없다면 이제 2범위 내에 있는지 검사한다.
'O'일 경우 2까지 검사할 수 있으므로 'O'인경우만, 검사한다. 또 다시 상하좌우로 나아가야 하기때문에
xx와 yy를 선언해 주어 유클리드 거리 2를 만든다.
이 값이 대기실 범위 내에 있고, 그 값이 사람'P'라면 answer에 0을 넣고, loop를 벗어난다. 'P'가 없다면 유클리드 2를 넘어가므로 추가 검사하지 않아도 된다.
'코딩테스트 연습 > 프로그래머스' 카테고리의 다른 글
[ 코딩테스트연습 / 프로그래머스 ] lv2 할인행사 java (0) | 2023.08.14 |
---|---|
[ 프로그래머스 > 2017 카카오코드 본선 ]LEVEL 3 : 리틀 프렌즈 사천성, solved by java (0) | 2020.11.04 |
[ 프로그래머스 > 월간 코드 챌린지 시즌1 ]LEVEL 2 : 쿼드압축 후 개수 세기, solved by java (0) | 2020.10.27 |
[ 프로그래머스 / 월간 코드 챌린지 시즌1] LEVEL 2 - 삼각 달팽이 : solved by Java (0) | 2020.10.25 |
[프로그래머스 ] level2 - 방금그곡; solved by JAVA (1) | 2020.10.24 |