https://www.acmicpc.net/problem/7562
- 예제 입력1
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1
- 예제 출력1
5
28
0
- 문제 접근
- 입력
- 테스트 케이스
- 각 테스트 케이스
- 첫째줄 ⇒ 체스판 한 변의 길이 (4 ~ 300)
- 둘째줄 ⇒ 현재 위치
- 셋째줄 ⇒ 목표 위치
- 각 테스트 케이스
- 테스트 케이스
- 출력
- 최소 이동 수
- 입력
- 문제 해결
- 나이트의 이동 가능 좌표 8칸을 선언
- 최소 이동이기 때문에 BFS가 더 적합하다고 판단
- DFS를 할 경우 300 x 300 체스판이 주어지면, 모든 경우를 다 탐색해야하기 때문
- 방문 여부 확인 배열 반드시 필요 → 없을 경우 무한 루프에 빠짐
- 기존 풀이 [메모리 : 72132 KB / 시간 : 312 ms]
// 체스판 크기, 목표 X 인덱스, 목표 Y 인덱스
static int chessLength, targetX, targetY;
// 나이트 이동 가능한 좌표
static int[] dx = {-1, -2, -2, -1, 1, 2, 1, 2};
static int[] dy = {-2, -1, 1, 2, -2, -1, 2, 1};
// chess에 이동 경로 수를 입력
static int[][] chess;
// 방문 배열 사용하지 않을 경우 무한 루프
static boolean[][] visited;
public static void main(String[] args) throws Exception {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int TestCase = Integer.parseInt(br.readLine());
for(int i = 0; i < TestCase; i++){
chessLength = Integer.parseInt(br.readLine());
chess = new int[chessLength][chessLength];
visited = new boolean[chessLength][chessLength];
st = new StringTokenizer(br.readLine());
int startX = Integer.parseInt(st.nextToken());
int startY = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
targetX = Integer.parseInt(st.nextToken());
targetY = Integer.parseInt(st.nextToken());
BFS(startX, startY);
sb.append(chess[targetX][targetY]).append("\n");
}
System.out.println(sb);
}
private static void BFS(int x, int y) {
// 처음 시작값을 큐에 넣고, 방문으로 체크 하고 시작
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{x, y});
visited[x][y] = true;
while(!queue.isEmpty()){
// 큐에 있는 값 추출
int[] coordinate = queue.remove();
// 현재 이동 횟수 저장
int currentMove = chess[coordinate[0]][coordinate[1]];
for(int i = 0; i < 8; i++){
// 다음 이동 X, Y 저장
int nextX = coordinate[0] + dx[i];
int nextY = coordinate[1] + dy[i];
// 이동이 불가능한 곳이라면, 방문한 곳이라면 무시
if(!isPossibleMove(nextX, nextY)) continue;
if(visited[nextX][nextY]) continue;
// 해당 좌표 방문 으로 체크
visited[nextX][nextY] = true;
// 현재 이동 횟수에서 1 증가
chess[nextX][nextY] = currentMove + 1;
// 타겟 X, Y라면 BFS 종료
if(isTarget(nextX, nextY)) return;
// 아직 타겟이 아니라면 queue에 추가
queue.offer(new int[]{nextX, nextY});
}
}
}
// 체스판 이내의 범위인지 체크하는 함수
private static boolean isPossibleMove(int x, int y){
return x >= 0 && y >= 0 && x < chessLength && y < chessLength;
}
// 목표한 좌표에 도달했는지 체크하는 함수
private static boolean isTarget(int x, int y){
return x == targetX && y == targetY;
}
'Coding Test > Problem Number' 카테고리의 다른 글
[Java] 바이러스 [2606번] (0) | 2024.07.29 |
---|---|
[Java] 특정 거리의 도시 찾기 [18352번] (0) | 2024.07.29 |
[Java] 완전 이진 트리 [9934번] (0) | 2024.07.27 |
[Java] 30번 [13116번] (0) | 2024.07.27 |
[Java] 신입 사원 [1946번] (0) | 2024.07.26 |