BFS: 백준 13549 오답노트

SeongGyun Hong·2025년 3월 7일

Python

목록 보기
31/34

https://www.acmicpc.net/problem/13549


1. 개요

  • 입력:
    • 수빈이의 위치: N=5N=5
    • 동생의 위치: K=17K=17
  • 이동 방법:
    • 걷기:
      xx1x\rightarrow x-1
      xx+1x\rightarrow x+1
      (각각 1초 소요)
    • 순간이동:
      x2xx\rightarrow 2x
      (0초 소요)
  • 제한:
    이동 가능한 범위는 0xMAX0\le x\le \texttt{MAX}이며, 여기서는 MAX=200\texttt{MAX}=200로 임의 설정하여 설명함.
  • 목표:
    수빈이가 동생에게 도달하는 최소 시간을 구함.
  • 핵심 아이디어:
    간선의 가중치가 0과 1인 문제이므로 0-1 BFS를 사용.
    • 순간이동(0초)은 덱의 앞쪽에 추가하여 우선 적으로 popleft()될 수 있도록 함.
    • 걷기(1초)는 덱의 뒤쪽에 추가.
    • 한 번 방문한 노드는 다시 처리하지 않도록 visited[x]\texttt{visited}[x] 배열로 관리.

2. 0-1 BFS 알고리즘 개요

  • 순간이동 (teleport):
    x2xx\rightarrow 2x

    • 조건: 2x2002x\le 200
    • 비용: 00\text{초}
    • 추가: 덱의 앞쪽 (appendleft)
  • 걷기 (walk):
    xx1x\rightarrow x-1
    xx+1x\rightarrow x+1

    • 비용: 11\text{초}
    • 추가: 덱의 뒤쪽 (append)
  • 방문 배열:
    visited[x]\texttt{visited}[x]

    • 초기값: 1-1 (미방문)
    • 한 번 방문하면 최소 시간 값이 저장되어 중복 방문을 방지함.
    • 즉, visited[x]의 초기값인 -1 에서 어떤 값으로 변경되었다는 사실은 수빈이가 해당 visited[x]x까지 이르는데 visited[x]만큼 걸렸다는 사실과 동일함.

3. 단계별 실행 과정 (MAX=200, N=5N=5, K=17K=17)

다음 표는 각 BFS 반복(iteration)마다의 현재 노드 xx,
해당 노드에서의 순간이동걷기 연산,
업데이트되는 visited\texttt{visited} 값, 그리고 덱(Queue)의 상태를 정리한 것

단계현재 노드 x(visited[x])x \, (\texttt{visited}[x])순간이동: 2x2x (조건, 새 방문시간)걷기: x1,  x+1x-1, \; x+1 (조건, 새 방문시간)덱(Queue) 상태 (왼쪽이 먼저 꺼냄)비고 및 방문 처리
0[55]초기 상태: visited[5]=0\texttt{visited}[5]=0
15(0)5 \, (0)2×5=102\times5=10
조건: 1020010\le200
설정: visited[10]=0\texttt{visited}[10]=0
51=45-1=4visited[4]=0+1=1\texttt{visited}[4]=0+1=1
5+1=65+1=6visited[6]=1\texttt{visited}[6]=1
[10,  4,  610,\; 4,\; 6]5에서 출발
210(0)10 \, (0)2×10=202\times10=20
조건: 2020020\le200
설정: visited[20]=0\texttt{visited}[20]=0
101=910-1=9visited[9]=0+1=1\texttt{visited}[9]=0+1=1
10+1=1110+1=11visited[11]=1\texttt{visited}[11]=1
[20,  4,  6,  9,  1120,\; 4,\; 6,\; 9,\; 11]10 처리
320(0)20 \, (0)2×20=402\times20=40
조건: 4020040\le200
설정: visited[40]=0\texttt{visited}[40]=0
201=1920-1=19visited[19]=0+1=1\texttt{visited}[19]=0+1=1
20+1=2120+1=21visited[21]=1\texttt{visited}[21]=1
[40,  4,  6,  9,  11,  19,  2140,\; 4,\; 6,\; 9,\; 11,\; 19,\; 21]20 처리
440(0)40 \, (0)2×40=802\times40=80
조건: 8020080\le200
설정: visited[80]=0\texttt{visited}[80]=0
401=3940-1=39visited[39]=0+1=1\texttt{visited}[39]=0+1=1
40+1=4140+1=41visited[41]=1\texttt{visited}[41]=1
[80,  4,  6,  9,  11,  19,  21,  39,  4180,\; 4,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41]40 처리
580(0)80 \, (0)2×80=1602\times80=160
조건: 160200160\le200
설정: visited[160]=0\texttt{visited}[160]=0
801=7980-1=79visited[79]=0+1=1\texttt{visited}[79]=0+1=1
80+1=8180+1=81visited[81]=1\texttt{visited}[81]=1
[160,  4,  6,  9,  11,  19,  21,  39,  41,  79,  81160,\; 4,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41,\; 79,\; 81]80 처리
6160(0)160 \, (0)2×160=3202\times160=320
조건: 320>200320>200 → 무시
1601=159160-1=159visited[159]=0+1=1\texttt{visited}[159]=0+1=1
160+1=161160+1=161visited[161]=1\texttt{visited}[161]=1
[4,  6,  9,  11,  19,  21,  39,  41,  79,  81,  159,  1614,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41,\; 79,\; 81,\; 159,\; 161]160 처리 (순간이동 무시)
74(1)4 \, (1)2×4=82\times4=8
조건: 82008\le200
설정: visited[8]=1\texttt{visited}[8]=1
41=34-1=3visited[3]=1+1=2\texttt{visited}[3]=1+1=2
4+1=54+1=5 → 무시 (이미 방문)
[8,  6,  9,  11,  19,  21,  39,  41,  79,  81,  159,  161,  38,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41,\; 79,\; 81,\; 159,\; 161,\; 3]4 처리
88(1)8 \, (1)2×8=162\times8=16
조건: 1620016\le200
설정: visited[16]=1\texttt{visited}[16]=1
81=78-1=7visited[7]=1+1=2\texttt{visited}[7]=1+1=2
8+1=98+1=9 → 무시 (이미 방문)
[16,  6,  9,  11,  19,  21,  39,  41,  79,  81,  159,  161,  3,  716,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41,\; 79,\; 81,\; 159,\; 161,\; 3,\; 7]8 처리
916(1)16 \, (1)2×16=322\times16=32
조건: 3220032\le200
설정: visited[32]=1\texttt{visited}[32]=1
161=1516-1=15visited[15]=1+1=2\texttt{visited}[15]=1+1=2
16+1=1716+1=17visited[17]=1+1=2\texttt{visited}[17]=1+1=2
[32,  6,  9,  11,  19,  21,  39,  41,  79,  81,  159,  161,  3,  7,  15,  1732,\; 6,\; 9,\; 11,\; 19,\; 21,\; 39,\; 41,\; 79,\; 81,\; 159,\; 161,\; 3,\; 7,\; 15,\; 17]16 처리: 도착, K=17K=17
  • 각 단계에서 순간이동은 비용 00으로 처리되어, 현재 노드의 방문 시간 그대로 다음 노드에 전달됨.
  • 걷기 연산은 현재 노드의 방문 시간에 11을 더해 할당되며
  • 이미 방문된 노드(예: 55, 99 등)는 다시 덱에 추가되지 않음.
  • 최종적으로 visited[17]=2\texttt{visited}[17]=2가 되어, 동생에게 도달하는 최소 시간이 22임을 확인할 수 있음.
  • 다만, 바로 17이 된 순간 정답이 도출되는 것은 아니고, 루프가 다 돌아서 해당하는 수(17)를 발견하게 되면 return됨.

4. 결론

  • 최단 시간: 22\text{초}
  • 핵심 포인트:
    • x2xx\rightarrow 2x (순간이동, 비용 00)는 덱의 앞쪽에 추가되어 우선 처리
    • xx1x\rightarrow x-1xx+1x\rightarrow x+1 (걷기, 비용 11)는 덱의 뒤쪽에 추가
    • visited[x]\texttt{visited}[x] 배열을 사용해 한 번 방문한 노드는 재방문하지 않으므로, 불필요한 연산과 무한 루프를 방지
    • 모든 이동은 0x2000\le x\le200 범위 내에서만 이루어짐.
profile
헤매는 만큼 자기 땅이다.

0개의 댓글