프로그래머스>코딩테스트 연습>2021 카카오 채용연계형 인턴십>거리두기 확인하기 - https://programmers.co.kr/learn/courses/30/lessons/81302
처음 문제를 보고 까다롭다고 생각했었는데, 막상 풀어보니 별거 아닌 문제다.
맨하탄 거리 2 이내에 있는 경우를 생각해보면, 다음과 같은 경우의 수가 있다.
1
에 있는 경우 = 상하좌우
2
에 있는 경우 = 직선
2
에 있는 경우 = 대각선
그림으로 표현해 보자면, 이렇다는 얘기다.
그러면 1번은 무조건 거리두기가 안지켜지는 것이고, 2번과 3번은 벽의 존재 유무에 따라 거리두기 여부가 정해진다.
이걸 5x5 격자를 하나하나 확인하며 사람이 있을 경우 위 3가지를 확인하면 된다! 하나라도 지켜지지 않는 경우가 있으면 0, 거리두기가 전부 지켜지면 1이다.
class Solution {
public int[] solution(String[][] places) {
int[] answer = new int[places.length];
for(int t=0; t<places.length; t++) {
String[] map = places[t];
boolean flag = false;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (map[i].charAt(j)=='P') {
if (isAroundExistPerson(i, j, map)) {
flag = true;
break;
}
}
}
if(flag){
answer[t] = 0;
break;
}
}
if(!flag){
answer[t] = 1;
}
}
return answer;
}
public static boolean isAroundExistPerson(int i, int j, String[] map){
// 상하좌우 확인
int[] mi = {0, 0, 1, -1};
int[] mj = {1, -1, 0, 0};
for (int d = 0; d < 4; d++) {
int ni = i + mi[d];
int nj = j + mj[d];
if(ni<0 || ni>=5 || nj<0 || nj>=5) continue;
if(map[ni].charAt(nj)=='P') return true;
}
// 상하좌우 맨하탄 거리 2 확인
int[] mi2 = {0, 0, 2, -2};
int[] mj2 = {2, -2, 0, 0};
for (int d = 0; d < 4; d++) {
int ni = i + mi2[d];
int nj = j + mj2[d];
if(ni<0 || ni>=5 || nj<0 || nj>=5) continue;
if(map[ni].charAt(nj)=='P') {
if(map[(i+ni)/2].charAt((j+nj)/2)!='X'){
return true;
}
}
}
// 대각선 확인
int[] mi3 = {1, 1, -1, -1};
int[] mj3 = {1, -1, 1, -1};
for (int d = 0; d < 4; d++) {
int ni = i + mi3[d];
int nj = j + mj3[d];
if(ni<0 || ni>=5 || nj<0 || nj>=5) continue;
if(map[ni].charAt(nj)=='P') {
if(!(map[i].charAt(nj)=='X' && map[ni].charAt(j)=='X')){
return true;
}
}
}
return false;
}
}
딱히 없음