※ 아이디어
- 현재 위치에서 주사위를 굴려 이동할 수 있는 번호를 큐에 담는다
- 이 때 그 칸이 사다리/뱀인 경우 → 사다리/뱀을 타고 도착하게될 칸의 번호로 담는다
- 사다리/뱀을 타고 이동하는 경우 주사위를 굴려 이동하는게 아니기 때문에 카운팅은 하지 않는다
- 사다리, 뱀의 정보는 꺼내 쓰기 좋게 Map을 사용하는게 좋겠다고 생각했다 ( O(1) 이니까)
- 문제에서 항상 100번 칸에 도착할 수 있는 입력만 주어진다 라고 했으니 큐에서 꺼낸놈의 번호가 100이면 바로 종료
(큐의 특성상 주사위를 굴린 횟수가 1, 1, ..., 1, 2, 2, ..., 2, 3, 3, ... 이런식으로 될거기때문에)
※ 놓쳤던 점
- 처음에는 사다리/뱀을 타고 도착하게 될 칸도 방문 체크를 했었는데, 그렇게 하게 되면 다른 경우를 체크하지 못할 수 있다
- 예) 사다리를 타고 50번에 도착해 방문체크를 했다 가정 → 주사위를 굴려 50번에 도착하거나, 뱀을 타고 50번에 도착하는 경우를 거르게 됨
- 사다리/뱀을 타고 도착한 곳에 또 사다리/뱀이 있는 경우를 생각하지 못했다
[맞은 코드]
import java.io.*;
import java.util.*;
public class Main {
static int n;
static int m;
static boolean[] visited;
static Map<Integer, Integer> ladderMap = new HashMap<>();
static Map<Integer, Integer> snakeMap = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
visited = new boolean[101];
// 1. 사다리 정보 입력
for(int i=0; i<n; i++) {
st = new StringTokenizer(br.readLine());
int ladderIndex = Integer.parseInt(st.nextToken());
int ladderDestination = Integer.parseInt(st.nextToken());
ladderMap.put(ladderIndex, ladderDestination);
}
// 2. 뱀 정보 입력
for(int i=0; i<m; i++) {
st = new StringTokenizer(br.readLine());
int snakeIndex = Integer.parseInt(st.nextToken());
int snakeDestination = Integer.parseInt(st.nextToken());
snakeMap.put(snakeIndex, snakeDestination);
}
int rv = bfs();
System.out.println(rv);
}
private static int bfs() {
// 3.bfs로 탐색
Queue<int[]> que = new LinkedList<>(); // {위치, 주사위굴린 횟수}
que.add(new int[] {1, 0}); // 시작위치=1, 굴린횟수=0
visited[1] = true;
while(!que.isEmpty()) {
int[] curNode = que.poll();
int curIndex = curNode[0];
int curTry = curNode[1];
if(curIndex == 100) {
return curTry;
}
for(int i=1; i<=6; i++) {
int nextIndex = curIndex + i;
if(nextIndex > 100) continue;
int dest = getDestination(nextIndex); // 사다리/뱀 최종 목적지 계산 (사다리 타고 도착한 곳에 또 사다리/뱀이 있는 경우 등)
if(!visited[dest]) {
visited[dest] = true;
que.add(new int[] {dest, curTry + 1});
}
}
}
return 0;
}
// 사다리/뱀이 있으면 최종 목적지까지 한번에 이동
private static int getDestination(int pos) {
while(ladderMap.containsKey(pos) || snakeMap.containsKey(pos)) {
if(ladderMap.containsKey(pos)) pos = ladderMap.get(pos);
else pos = snakeMap.get(pos);
}
return pos;
}
}
[틀린 코드]
- 사다리/뱀을 타고 이동할 때 방문체크를 했었다
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
boolean[] visited = new boolean[101];
// 1. 사다리 정보 입력
Map<Integer, Integer> ladderMap = new HashMap<>();
for(int i=0; i<n; i++) {
st = new StringTokenizer(br.readLine());
int ladderIndex = Integer.parseInt(st.nextToken());
int ladderDestination = Integer.parseInt(st.nextToken());
ladderMap.put(ladderIndex, ladderDestination);
}
// 2. 뱀 정보 입력
Map<Integer, Integer> snakeMap = new HashMap<>();
for(int i=0; i<m; i++) {
st = new StringTokenizer(br.readLine());
int snakeIndex = Integer.parseInt(st.nextToken());
int snakeDestination = Integer.parseInt(st.nextToken());
snakeMap.put(snakeIndex, snakeDestination);
}
// 3.bfs로 탐색
Queue<int[]> que = new LinkedList<>(); // {위치, 주사위굴린 횟수}
que.add(new int[] {1, 0}); // 시작위치=1, 굴린횟수=0
int minTry = 17;
while(!que.isEmpty()) {
int[] curNode = que.poll();
int curIndex = curNode[0];
int curTry = curNode[1];
visited[curIndex] = true;
if(curIndex == 100) {
minTry = Math.min(minTry, curTry);
}
// 현재 위치가 사다리 또는 뱀이면 주사위를 굴리지 않고 바로 이동
if(ladderMap.containsKey(curIndex)) {
que.add(new int[] {ladderMap.get(curIndex), curTry}); // 주사위는 안굴리기 때문에 1 증가 해주지 않음
continue;
}
if(snakeMap.containsKey(curIndex)) {
que.add(new int[] {snakeMap.get(curIndex), curTry}); // 주사위는 안굴리기 때문에 1 증가 해주지 않음
continue;
}
for(int i=1; i<=6; i++) { // 주사위를 굴려서 나올수 있는 경우 6가지
int nextIndex = curIndex + i;
if(nextIndex<= 100 && !visited[nextIndex])
que.add(new int[] {nextIndex, curTry + 1});
}
}
System.out.println(minTry);
}
}

'코딩테스트 > BOJ' 카테고리의 다른 글
| [BOJ] 1325-효율적인 해킹(Java) - BFS/시간초과 (0) | 2026.04.13 |
|---|---|
| [Java] 백준 2745 - 진법 변환 (0) | 2023.10.02 |
| [Java] 백준 2675 - 문자열 반복 (0) | 2023.09.28 |
| [C] 백준 10988- 팰린드롬인지 확인하기 (0) | 2023.07.19 |
| [C] 백준 9086 - 문자열 (0) | 2023.07.18 |
