문제 링크
문제 풀이
문제 설명
각 응시자들 간의 맨해튼 거리가 2 이하인 응시자들이 있는지를 확인하는 문제이다. 단, 파티션으로 막혀있다면 맨해튼 거리상 2 이하에 있더라도 상관없다.
문제 접근 방식
대기실은 총 5개이며 각 대기실 크기는 5 x 5이다.
단순하게 접근하면 각 응시자들 간의 거리를 구하고 그 사이에 파티션이 있는지 체크하면 될 거라고 판단했다.
파티션으로 막히는 경우는 ‘PXP’처럼 응사자들 사이에 파티션이 있는 경우밖에 존재하지 않기 때문이다.
단, 대각선 방향에 있는 경우 2가지 경우의 수를 고려해야한다.
문제 1
해당 방식을 고려한 코드는 아래와 같으나, 몇몇 테스트케이스에서 에러가 발생했다.
import java.util.*;
class Solution {
// 맨해튼 거리 계산 함수
public int manhattan(int[] start, int[] end) {
int y = Math.abs(start[0] - end[0]);
int x = Math.abs(start[1] - end[1]);
return y + x;
}
// 접근 가능한지 확인하는 함수
public boolean canGo(char[][] map, int[] start, int[] end) {
// 거리가 1이면 true 반환
if (manhattan(start, end) == 1)
return true;
// 거리가 2일 경우 파티션 계산
int y1 = start[0];
int y2 = end[0];
int x1 = start[1];
int x2 = end[1];
if (y1 == y2) {
int mid = (x1 + x2) / 2;
return map[y1][mid] != 'X';
}
if (x1 == x2) {
int mid = (y1 + y2) / 2;
return map[mid][x1] != 'X';
}
// 대각선인 경우
return map[y1][x2] != 'X' && map[y2][x1] != 'X';
}
public int[] solution(String[][] places) {
int[] answer = new int[5];
Arrays.fill(answer, 1);
for (int T = 0; T < 5; T++) {
String[] place = places[T];
char[][] map = new char[5][5];
List<int[]> part = new ArrayList<>();
// map 할당 및 응시자 위치 할당
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
map[i][j] = place[i].charAt(j);
if (map[i][j] == 'P') {
part.add(new int[] {i, j});
}
}
}
// 응시자 간 맨해튼 거리 계산
for (int i = 0; i < part.size(); i++) {
for (int j = i + 1; j < part.size(); j++) {
// 맨해튼 거리 <= 2라면 파티션 여부 파악
int[] start = part.get(i);
int[] end = part.get(j);
if (manhattan(start, end) <= 2) {
if (canGo(map, start, end)) {
answer[T] = 0;
}
}
}
}
}
return answer;
}
}이유는 대각선일 경우 파티션 유무 조건식이 잘못된 것이 문제였다.
// return map[y1][x2] != 'X' && map[y2][x1] != 'X';
문제를 금방 파악해서 수정할 수 있었다.
최종 코드
최종 코드는 아래와 같다.
import java.util.*;
class Solution {
// 맨해튼 거리 계산 함수
public int manhattan(int[] start, int[] end) {
int y = Math.abs(start[0] - end[0]);
int x = Math.abs(start[1] - end[1]);
return y + x;
}
// 접근 가능한지 확인하는 함수
public boolean canGo(char[][] map, int[] start, int[] end) {
// 거리가 1이면 true 반환
if (manhattan(start, end) == 1)
return true;
// 거리가 2일 경우 파티션 계산
int y1 = start[0];
int y2 = end[0];
int x1 = start[1];
int x2 = end[1];
if (y1 == y2) {
int mid = (x1 + x2) / 2;
return map[y1][mid] != 'X';
}
if (x1 == x2) {
int mid = (y1 + y2) / 2;
return map[mid][x1] != 'X';
}
// 대각선인 경우
return map[y1][x2] != 'X' || map[y2][x1] != 'X';
}
public int[] solution(String[][] places) {
int[] answer = new int[5];
Arrays.fill(answer, 1);
for (int T = 0; T < 5; T++) {
String[] place = places[T];
char[][] map = new char[5][5];
List<int[]> part = new ArrayList<>();
// map 할당 및 응시자 위치 할당
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
map[i][j] = place[i].charAt(j);
if (map[i][j] == 'P') {
part.add(new int[] {i, j});
}
}
}
// 응시자 간 맨해튼 거리 계산
for (int i = 0; i < part.size(); i++) {
for (int j = i + 1; j < part.size(); j++) {
// 맨해튼 거리 <= 2라면 파티션 여부 파악
int[] start = part.get(i);
int[] end = part.get(j);
if (manhattan(start, end) <= 2) {
if (canGo(map, start, end)) {
answer[T] = 0;
}
}
}
}
}
return answer;
}
}