피곤..스터디 쉬고 싶은 하루다 🥲
코드가 개발새발이지만
→ 이동하였을 때 만나는 응시자가 없는 경우, 방문처리를 합니다
교육에 들어오고 코테를 거의 안 풀었더니 문제 푸는데 오랜 시간이 걸리고 코드 가독성이 매우 떨어진당..ㅠㅠ
public class Main {
private static int LEN = 5;
private boolean[][] starts; //
private int[][] move = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public int[] solution(String[][] places) {
int[] answer = {};
starts = new boolean[LEN][LEN];
answer = checkRoom(places);
return answer;
}
public int[] checkRoom(String[][] places) {
int[] ans = new int[5];
int roomNumb = 0;
boolean success = false;
for (String[] room : places) {
// 방문 초기화
initBoolArr(starts);
success = true;
// 각 방의 , 각 응시자가 시작점이 되어 수행한다
for (int r = 0; r < LEN; r++) {
for (int c = 0; c < LEN; c++) {
if (room[r].charAt(c) != 'P' || starts[r][c] == true)
continue;
// 응시자인경우
// 거리두기 실패한 경우
if ((success = isSuccess(r, c, room)) == false) {
ans[roomNumb] = 0;
success = false;
break;
}
}
if (!success)
break;
}
if (success) {
ans[roomNumb] = 1;
}
roomNumb++;
}
return ans;
}
// 각 대기실 마다 visit 을 초기화해줘야 합니다
public void initBoolArr(boolean[][] arr) {
for (int i = 0; i < LEN; i++) {
Arrays.fill(arr[i], false);
}
}
// r,c 에서 시작하여 맨해튼 거리 2 내의 경로에 다른 응시자가 존재하는지 확인
public boolean isSuccess(int r, int c, String[] room) {
LinkedList<int[]> q = new LinkedList<>();
// 각 출발점마다 visit 은 초기화되어야 합니다
boolean[][] visit = new boolean[LEN][LEN];
q.addLast(new int[] {r, c, 0}); // row, column , depth
visit[r][c] = true;
// bfs 상으로는 depth 가 2 이하인 범위 내에서 존재하면 안 되는 것
while (!q.isEmpty()) {
int[] cur = q.pollLast();
for (int dir = 0; dir < move.length; dir++) {
int nr = cur[0] + move[dir][0];
int nc = cur[1] + move[dir][1];
// 범위 초과
if (nr < 0 || nc < 0 || nr >= LEN || nc >= LEN)
continue;
// 이미 방문한 경우
if (visit[nr][nc])
continue;
// 칸막이가 있는 경우
if (room[nr].charAt(nc) == 'X')
continue;
// 현재 노드까지의 거리가 2
if (cur[2] >= 2) continue;
// 다른 응시자를 만난 경우
if (room[nr].charAt(nc) == 'P' ) {
return false;
}
// 다른 응시자를 만나지 않은 경우
visit[nr][nc] = true;
q.addLast(new int[] {nr, nc, cur[2] + 1});
}
}
return true;
}
}
그런데 이 문제에서
// 현재 노드까지의 거리가 2
if (cur[2] >= 2) continue;
이 부분 대신
public boolean isSuccess(int r, int c, String[] room) {
LinkedList<int[]> q = new LinkedList<>();
boolean[][] visit = new boolean[LEN][LEN];
q.addLast(new int[] {r, c, 0}); // row, column , depth
visit[r][c] = true;
// bfs 상으로는 depth 가 2 이하인 범위 내에서 존재하면 안 되는 것
while (!q.isEmpty()) {
int[] cur = q.pollLast();
// 💥 여기서 확인한다고 생각했는데 이렇게 하면 틀렸습니다가 나온당
if (cur[2] >= 2)
break;
for (int dir = 0; dir < move.length; dir++) {
int nr = cur[0] + move[dir][0];
int nc = cur[1] + move[dir][1];
// 범위 초과
if (nr < 0 || nc < 0 || nr >= LEN || nc >= LEN)
continue;
// 이미 방문한 경우
if (visit[nr][nc])
continue;
// 칸막이가 있는 경우
if (room[nr].charAt(nc) == 'X')
continue;
// 다른 응시자를 만난 경우
if (room[nr].charAt(nc) == 'P') {
return false;
}
// 다른 응시자를 만나지 않은 경우
visit[nr][nc] = true;
q.addLast(new int[] {nr, nc, cur[2] + 1});
}
}
return true;
}
이렇게 하면 테스트 케이스 31 번만 틀렸습니다가 나오더라.
졸려서 이유를 생각하고 싶지 않다
누워서 생각해보니 위의 경우는 break 를 했기 때문에 문제가 되는거였다
if (cur[2] >= 2)
break; -> continue; 로 변경해주면 정답이 된다