[java]숨바꼭질 2 - 백준12851
문제
풀이
문제 해석을 하자면,
- 숨바꼭질 문제는 시리즈로 여러개 존재한다.
- 1~4 까지 풀어봤고 이 문제만 정리하고자 한다. -> visited 사용시점 확인이 목표!
풀이
- DP도 가능하고 BFS도 가능하다. BFS가 더 간단하다.
- 한번 움직일 때 1초이며 최소 시간이니 BFS 적합 (최단거리)
- BFS 일반 로직을 사용하면 바로 구할 수 있는데, visited 를 갱신하는 시점이 중요하다.
- 본인이 생각하는 갱신 시점은 2가지 이다.
-
qu.poll()
사용하는 그 시점에visited = true
하느냐 - next 값 구해서
큐에 삽입
하는 그 시점에visited = true
하느냐
-
- 본인은 보통 “큐에 삽입 시점” 에 갱신하지만, 이 문제에서는 “qu.poll()” 시점에 사용하자!
- 만일 “큐 삽입 시점” 에 갱신하면 여러 예외처리 할 것이 생기게 됨.
코드
static int N, K;
static int result, result2; // 동생 찾는 시간, 동생 찾는 방법 수
static boolean[] visited;
static void check(int cur, Deque<Integer> qu) {
// 3가지 연산 경우로 가지치기
if(cur+1 <= K+1 && !visited[cur+1]) { // cur+1 범위 방지 필수
qu.offer(cur + 1);
}
if(cur*2 <= K*2 && !visited[cur*2]) { // cur*2 범위 방지 필수
qu.offer(cur * 2);
}
if(cur-1 >= 0 && !visited[cur-1]) { // cur-1 음수 방지 필수
qu.offer(cur - 1);
}
}
static void bfs(){
Deque<Integer> qu = new ArrayDeque<>();
qu.offer(N);
visited[N] = true;
boolean endPoint = false; // 종료시점 기록
while(!qu.isEmpty()) {
if(endPoint) return;
int size = qu.size();
result++;
for (int s = 0; s < size; s++) {
int cur = qu.poll();
if(cur==K) {
result2++;
endPoint=true; // 해당 큐 과정 끝나면 종료할 목적
continue;
}
visited[cur] = true;
check(cur, qu);
}
}
}
public static void main(String[] args) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(stk.nextToken());
K = Integer.parseInt(stk.nextToken());
visited = new boolean[300005]; // 2X 연산 때문에 크기 넉넉히 잡았음
//run
bfs();
//output
System.out.println(result-1);
System.out.println(result2);
}
느낀점
생략
댓글남기기