문제
숨바꼭질 2 (https://www.acmicpc.net/problem/12851)
풀이
1. 초기 접근
- 문제조건 해석
- 움직임, 경로에 대한 문제고, 간선의 길이가 1로 정해져있다.
- BFS 문제다.
- 움직임, 경로에 대한 문제고, 간선의 길이가 1로 정해져있다.
- 알고리즘
- 이전 1697. 숨바꼭질 문제에서 경로의 갯수가 추가된 것이다.
- 이제 우리는 2가지를 생각해야 한다.
- 하나는, n 까지 오는데의 최소 시간(
time
) 과 이를 저장하는 방법 (visited[n]
) 이고, - 다른 하나는, n 까지 최소 시간으로 오는 방법의 수(
ways[n]
)다.
- 하나는, n 까지 오는데의 최소 시간(
- 어떤 좌표 j 가 있다고 하자. 이 좌표에 오는 방법에는 3가지 방법이 있을 것이다. (
j-1
,j+1
,j/2
에서 온다.)
경우가 3가지 이므로, j에 오는 방법은 3가지 일까?
아니다. 우리는 최소 시간 을 고려해야 한다. 3가지 각 경우에서 j로 갈 때, 어떤게 최소시간인지를 생각해줘야 한다. - 예를 들어, j=10 라고 해보자. 9->10, 11->10, 5->10, 이렇게 3가지 경우가 있을텐데, 9->10 으로 갈 때의 시간은 5이고, 11->10은 3, 5->10도 3이라고 해보자.
이 경우, 11->10과 5->10은 10으로 최소시간만으로 오는 경우이므로, 두 가지 모두 가능하고, 9->10의 경우는 최소시간이 아니므로 (5 > 3 이므로) 이 경우는 불가능하다. - 따라서 아래 코드의 조건문에는 범위 체크 뿐 아니라, 해당 방법이 최소시간을 만족하는지 체크하는
time + 1 <= visited[j]
이 들어가게 된다.
- 코드
import sys
from collections import deque
n, k = list(map(int, sys.stdin.readline().split()))
def bfs(n, k):
# n: 시작지점, k: 도착지점
# 바로바로 처리할 수 있는 경우 2가지.
if n == k:
return 0, 1
if n > k:
return n-k, 1
# visited[j] : j 까지 오는데 얼마의 최소 time을 저장.
# ways[j] : j 까지 최소 time으로 오는 방법의 수 저장.
q, visited, ways = deque([n]), [float('inf')]*100001, [0]*100001
time, count, success = 0, 0, False
ways[n] = 1
visited[n] = 0
while q and not success:
size = len(q)
for _ in range(size):
cur = q.popleft()
next_move = [cur-1, cur+1, cur*2]
for j in next_move:
if j >= 0 and j <= 100000 and time + 1 <= visited[j]:
ways[j] += 1
visited[j] = time + 1
if j == k:
success = True
if not success:
q.append(j)
time += 1
return visited[k], ways[k]
time, count = bfs(n, k)
print(time)
print(count)
'취업과 기본기 튼튼 > 코딩 테스트 노트' 카테고리의 다른 글
[BOJ] 13913. 숨바꼭질 4 (0) | 2019.04.07 |
---|---|
[BOJ] 13549. 숨바꼭질 3 (0) | 2019.04.07 |
[BOJ] 7569. 토마토 (0) | 2019.04.07 |
[BOJ ]7576. 토마토 (0) | 2019.04.07 |
[BOJ] 2644. 촌수 계산 (0) | 2019.04.07 |