개요
BFS는 최단거리를 구하는 경우 가중치가 1일 때 사용할 수 있다.
이 문제는 동생과 형의 시작 지점이 같을 경우 반례 때문에 삽질 좀 했다.
자신 스스로 반례를 찾는 습관을 가지는 것을 추천한다!
문제
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
풀이
1. 형의 시작지점을 큐에 추가하고 방문처리를 한다.
2. 큐에서 노드를 꺼낸다.
3. 꺼낸 노드에서 + 1, - 1, * 2 지점의 유효성 검사를 한다.
(유효성 검사는 1. 해당 노드 좌표의 유효성 2. 미 방문한 곳인지 를 확인한다.)
4. 유효한 경우 큐에 노드를 추가하고 방문처리한다. (이때 기존의 노드 값 + 1을 저장하여 일수를 계산한다.)
5. 큐가 비거나 꺼낸 노드의 값 = 동생의 위치 일때까지 2 ~ 4를 반복한다.
6. 반복문을 탈출했을 때 isVisit[]의 값 - 1을 출력한다. (시작점을 1로 잡았기 때문에 걸린 일수를 계산하기 위해서는 -1을 해줘야 한다.)
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static int n, k;
static int isVisit[];
static Queue<Integer> queue = new LinkedList<>();
public static void main(String[] args) throws IOException {
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
isVisit = new int[100_001];
int answer = solve();
System.out.println(answer);
}
public static int solve(){
int result = -1;
// 형의 시작 노드 큐에 추가
queue.add(n);
// 방문 처리
isVisit[n] = 1;
while (!queue.isEmpty()){
int location = queue.poll();
// 큐에서 꺼낸 값이 동생의 위치인 경우
if(location == k) {
result = isVisit[location];
break;
}
if(checkLocation(location - 1)){
queue.add(location - 1);
isVisit[location - 1] = isVisit[location] + 1;
}
if(checkLocation(location + 1)){
queue.add(location + 1);
isVisit[location + 1] = isVisit[location] + 1;
}
if(checkLocation(location * 2)){
queue.add(location * 2);
isVisit[location * 2] = isVisit[location] + 1;
}
}
// 시작점을 1 초 걸린다고 잡았으므로 -1 한 값을 반환
return result - 1;
}
private static boolean checkLocation(int i) {
if(i < 0 || i > 100_000) return false;
if(isVisit[i] > 0) return false;
else return true;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 1753 : JAVA] 최단경로 / 다익스트라 (0) | 2020.02.09 |
---|---|
[백준 2206 : JAVA] 벽 부수고 이동하기 / BFS (0) | 2020.02.09 |
[백준 7569 : JAVA] 토마토 / BFS (0) | 2020.02.09 |
[백준 7576 : JAVA] 토마토 / BFS (0) | 2020.02.09 |
[백준 2178 : JAVA] 미로탐색 / DFS BFS 특징 (0) | 2020.01.30 |