23.12.12 14:30 작성
·
252
0
package com.company.대기업유제.그래프;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
class 공굴리기 {
public int solution(int[][] board, int[] s, int[] e) {
/**
* n * m 격자판
* 0은 빈공간 1은 벽
*
* 공은 격자의 상하 좌우 네방향으로 빈공간을 이동할수있음 벽을 만나면 멈춘다.
* s 공의 위치
* e 공의 목표지점
* 목표위치까지 최단거리 ㄱ
* 목표지점까지 도달못하면 -1
*
* */
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, -1, 0, 1};
PriorityQueue<Candidate> queue = new PriorityQueue<Candidate>();
Map<String, Integer> minPosMap = new HashMap<>();
Pos first = new Pos(s[1], s[0]);
for (int i = 0; i < 4; i++) {
queue.add(new Candidate(first, 0, i));
}
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Candidate candi = queue.poll();
Pos poll = candi.pos;
//벽을 만나지 않았으면 가던 방향으로 계속 이동
if(!candi.frontWall(board, dx, dy)){
Pos newPos = new Pos(candi.pos.x + dx[candi.direction], candi.pos.y + dy[candi.direction]);
Candidate newCandi = new Candidate(newPos, candi.cnt + 1, candi.direction);
Integer basePrice = minPosMap.getOrDefault(newPos.getName(), Integer.MAX_VALUE);
if (basePrice < newCandi.cnt) continue;
queue.add(newCandi);
minPosMap.put(newPos.getName(), newCandi.cnt);
}else{ //벽을 만나면 그때 방향 돌리기
//벽을 만났을때만 목표지점 체크하기
if (poll.x == e[1] && poll.y == e[0]) {
// print(board);
return minPosMap.getOrDefault(poll.getName(), Integer.MAX_VALUE);
}
for (int j = 0; j < 4; j++) {
int moveX = dx[j] + poll.x;
int moveY = dy[j] + poll.y;
if (moveX < 0 || moveY < 0 || moveX >= board[0].length || moveY >= board.length) continue;
// * 0은 빈공간 1은 벽
if(board[moveY][moveX] == 1) continue;
Pos newPos = new Pos(moveX, moveY);
Candidate newCandi = new Candidate(newPos, candi.cnt + 1, j);
Integer basePrice = minPosMap.getOrDefault(newPos.getName(), Integer.MAX_VALUE);
if (basePrice < newCandi.cnt) continue;
queue.add(newCandi);
minPosMap.put(newPos.getName(), newCandi.cnt);
}
}
}
}
return -1;
}
public void print(int[][] board){
for (int i = 0; i < board.length; i++) {
for (int j : board[i]) {
System.out.print(j + " ");
}
System.out.println();
}
}
class Pos {
int x;
int y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
public String getName() {
return x + "" + y;
}
}
class Candidate implements Comparable<Candidate> {
Pos pos;
int cnt;
int direction;
public Candidate(Pos pos, int cnt, int direction) {
this.pos = pos;
this.cnt = cnt;
this.direction = direction;
}
public boolean frontWall(int[][] board, int[] dx, int[] dy){
int moveX = dx[direction] + pos.x;
int moveY = dy[direction] + pos.y;
if (moveX < 0 || moveY < 0 || moveX >= board[0].length || moveY >= board.length) return true;
// * 0은 빈공간 1은 벽
if(board[moveY][moveX] == 1) return true;
return false;
}
@Override
public int compareTo(Candidate o) {
return this.cnt - o.cnt;
}
}
public static void main(String[] args) {
공굴리기 T = new 공굴리기();
System.out.println(T.solution(new int[][]{{0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0}, {1, 0, 1, 1, 1, 0}, {1, 0, 0, 0, 0, 0}}, new int[]{1, 0}, new int[]{4, 5}));
System.out.println(T.solution(new int[][]{{0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0}, {1, 0, 1, 1, 1, 0}, {1, 0, 0, 0, 0, 0}}, new int[]{0, 0}, new int[]{4, 2}));
System.out.println(T.solution(new int[][]{{1, 0, 1, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {1, 1, 0, 1, 1}, {0, 0, 0, 0, 0}}, new int[]{0, 3}, new int[]{4, 2}));
System.out.println(T.solution(new int[][]{{0, 1, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 1, 1, 0, 1, 1}, {0, 0, 0, 0, 0, 0}}, new int[]{0, 0}, new int[]{4, 5}));
System.out.println(T.solution(new int[][]{{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0}}, new int[]{0, 0}, new int[]{4, 3}));
}
}
문제를 다 이해했다고 생각했는데 한참 헤맸네요.. ㅜㅜ
AI인턴이 어떻게 동작하는지 모르겠지만 AI로 답변 달아주셔도 됩니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
이승환님의 코드를 살펴보았습니다. 공 굴리기 문제 풀이에서 BFS(Breadth-First Search, 너비 우선 탐색) 알고리즘과 우선순위 큐를 사용하여 최단 거리를 찾는 논리를 잘 구성하셨습니다. 그러나 여러 테스트 케이스를 시도해 볼 때 예상치 못한 결과를 만나셨나 봅니다. 차분히 디버깅하면서 각 단계에서의 변수 상태를 살펴보고, 조건문이 올바르게 작동하는지, 예외 사항을 처리했는지 확인해 볼 필요가 있습니다.
문제 풀이에서 고려해야 하는 몇 가지 사항은 다음과 같습니다:
1. 벽과의 충돌 조건을 정확히 판단하고 있는지 검토해보세요.
2. 최단 거리 값을 올바르게 업데이트하고 있는지 확인해보세요.
3. 우선순위 큐를 사용할 때, 동일 거리에 대한 다른 경로가 있을 경우의 처리를 확인해보세요.
4. 경계값 처리가 올바르게 되고 있는지, 배열의 인덱스를 벗어나는지 검사해야 합니다.
더 깊이 있는 분석이 필요할 경우에는 해당 강의의 커뮤니티 질문&답변 게시판을 통해 질문하시면, 강사님 혹은 다른 학습자분들도 도움을 줄 수 있습니다. 문제의 핵심적인 부분에 대한 설명이 필요하시다면, 강의 내용을 복습하며 관련 개념을 다시 한 번 점검해보시는 것도 좋습니다.
본인의 코드를 다시 한 번 꼼꼼히 확인하면서 문제의 요구사항에 맞게 수정해보세요. 모르는 부분이 있거나 피드백이 필요하시다면, 언제든 질문해주시기 바랍니다. 화이팅입니다!