728x90
반응형
https://www.acmicpc.net/problem/1697
문제 파악
- 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다.
<알고리즘 분류>
-그래프 이론
-그래프 탐색
-너비 우선 탐색
접근 방법
-최소시간을 구해 리턴해야 하므로 BFS접근을 사용한다.
-정수 배열을 담는 큐 자료형 사용
-정수 배열에는 수빈이의 위치 x와 걸린 시간이 담긴다.
코드 구현
package com.baekjoon;
public class p1697_숨바꼭질 {
public static int p1697_숨바꼭질() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
//어떻게 이동할 지 모르므로(뒤로 갔다 앞으로 갔다) 경우의 수는 무한함
int MAX = 100000;
boolean[] visited = new boolean[MAX];//각 방문 경로마다 발자취 남기기(갔던 길 또 못감)
//최단거리 큐
Queue<int[]> queue = new ArrayDeque<>();
queue.add(new int[]{n,0});
visited[n] = true;
while(!queue.isEmpty()){
int[] node = queue.remove();
int path = node[0];
int time = node[1];
if(path==k){
return time;
}
int[] toGo = new int[]{path+1,path*2,path-1};
for(int x:toGo){
if(x>=0 && x<=MAX && !visited[x]){
queue.add(new int[]{x,time+1});
visited[x] = true;
}
}
}
return -1;
}
public static void main(String[] args) throws IOException {
int result = p1697_숨바꼭질();
System.out.println(result);
}
}
배우게 된 점
노드를 제거할 때 방문하는 방식이 아닌, 노드를 삽입할 때 방문 체크를 해주는 것이 참신했다.
왜 노드를 삽입할 때 이례적으로 방문 체크를 해줄까? 실제로 노드 제거 시, 평소처럼 방문 체크해주니 컴파일 에러 발생.
챗 GPT에게 물어봤다.
이론적으로 큐에서 노드를 뺄 때 방문 처리를 해도 결과는 동일할 수 있습니다. 하지만 큐에 넣을 때 방문 처리를 하는 방식이 더 효율적입니다. 그 이유는 다음과 같습니다.
차이점:
- 큐에 중복 노드가 여러 번 들어가는 문제:
- 큐에서 방문 처리를 하는 경우, 중복된 노드가 여러 번 큐에 들어갈 수 있습니다. 예를 들어, 수빈이가 n에 있을 때, n + 1, n - 1, n * 2로 이동할 수 있는데, 방문 처리를 하지 않고 큐에 넣으면 중복된 값들이 여러 번 큐에 들어갈 가능성이 있습니다.
- 만약 n + 1을 여러 경로로 갈 수 있다면 큐에서 해당 위치를 여러 번 꺼내야 할 수 있습니다.
- 불필요한 큐 크기 증가:
- 큐에 중복된 노드가 들어가면, 큐의 크기가 커져 메모리 사용량이 증가하고, 중복된 노드를 처리해야 하기 때문에 CPU 시간이 더 소모됩니다.
- 큐에서 중복된 노드를 꺼낼 때는 방문 처리를 한다고 해도, 그 노드를 큐에 넣는 과정에서 메모리와 시간을 낭비할 수 있습니다.
- 큐에서 방문 처리를 하면 탐색 속도가 느려질 수 있음:
- 큐에서 방문 처리를 하게 되면, 큐에 이미 같은 노드가 여러 번 들어가므로, 방문 처리가 이뤄질 때마다 해당 노드의 처리가 반복됩니다.
- BFS에서는 같은 노드를 여러 번 처리할 필요가 없으므로, 큐에 넣을 때 방문 처리를 하면 큐의 크기를 줄여 불필요한 중복 탐색을 방지할 수 있습니다.
즉, x+1이나 x-1이나 x*2이나, 이 연산 값들 중 중복이 있을 수도 있다는 것이다!
그럼, 같은 값을 굳이, 넣을 필요가 없으니
애초에 반복문 돌면서 큐에 넣을 때, 제해버리자는 것이다.
반응형
'alorithm > Baekjoon' 카테고리의 다른 글
[백준] 5014번: 스타트링크 (3) | 2024.09.07 |
---|---|
[백준] 2648번 : 안전 영역 (2) | 2024.09.02 |
[백준] 바이러스 -재 풀이 (0) | 2024.08.13 |
[백준] 미로 탐색 (0) | 2024.08.13 |
[백준] 2667번: 단지번호붙이기 (0) | 2024.08.13 |