알고리즘 공부/bfs,dfs

백준1697번 with Kotlin #bfs에서 visit의 중요성 #if 우선순위

_우지 2021. 8. 12. 15:34

숨바꼭질 성공출처다국어

한국어   

시간 제한메모리 제한제출정답맞은 사람정답 비율

2 초 128 MB 117934 33197 20640 24.973%

문제

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.

입력

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

출력

수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

예제 입력 1 복사

5 17

예제 출력 1 복사

4

힌트

수빈이가 5-10-9-18-17 순으로 가면 4초만에 동생을 찾을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.*
 
data class xt(val x:Int,val t:Int){
 
}
val br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))
 
fun main()=with(br){
    val q:Queue<xt> = LinkedList<xt>()
    val (n,k) = readLine()!!.split(" ").map{it.toInt()}
 
    val visit = BooleanArray(100001){false}
    q.add(xt(n,0))
    visit[n]=true
    var ans = 0
    if(n==k)
        bw.write("$ans")
    else {
        if(n<k) {
            while (!q.isEmpty()) {
                var a = q.poll()
                if (k == a.x + 1) {
                    ans = a.t + 1
                    break
                } else {
                    if( a.x+1<=100000 && !visit[a.x+1] ) {
                        visit[a.x+1]=true
                        q.add(xt(a.x + 1, a.t + 1))
                    }
                }
 
                if (k == a.x - 1) {
                    ans = a.t + 1
                    break
                } else {
                    if(a.x-1>=0 && !visit[a.x-1]  ) {
                        visit[a.x-1]=true
                        q.add(xt(a.x -1 , a.t + 1))
                    }
                }
                if (k == a.x * 2) {
                    ans = a.t + 1
                    break
                } else {
                    if( a.x*2<=100000 && !visit[a.x*2] ) {
                        visit[a.x*2]=true
                        q.add(xt(a.x*2, a.t + 1))
                    }
                }
            }
            bw.write("$ans")
        }
        else{
            bw.write("${n-k}")
        }
    }
    bw.flush()
    bw.close()
}
 
 
cs

 이 문제를 풀면서 배울 수 있었던 것은..

1.  visit[n]=true  

visit이라는 배열을 사용해서 중복되는 부분을 줄이면 시간적 효율을 얻을 수 있고,

 

2. if(a.x-1>=0 && !visit[a.x-1] ) 구문에서, if(!visit[a.x-1]  &&  a.x-1>=0)  과 비교했을때

index오류를 없애기 위해서는 index의 조건을 파악하는 코드를 앞에 넣어야지, 오류가 발생하지 않는다.

왜냐하면 false && true 일경우 false를 파악하자 마자, 뒤에 코드는 고려하지 않기 때문이다.