🧩 Problem Solving/[λ°±μ€€]

[λ°±μ€€] 12851 μˆ¨λ°”κΌ­μ§ˆ 2 (python 파이썬)

μ œλ΄‰μ•„ 2022. 7. 10. 22:13

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

 

12851번: μˆ¨λ°”κΌ­μ§ˆ 2

μˆ˜λΉˆμ΄λŠ” 동생과 μˆ¨λ°”κΌ­μ§ˆμ„ ν•˜κ³  μžˆλ‹€. μˆ˜λΉˆμ΄λŠ” ν˜„μž¬ 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 μžˆλ‹€. μˆ˜λΉˆμ΄λŠ” κ±·κ±°λ‚˜ μˆœκ°„μ΄λ™μ„ ν•  수 μžˆλ‹€. λ§Œμ•½, 수빈이의 μœ„μΉ˜κ°€ X일 λ•Œ

www.acmicpc.net


아이디어

 

1. bfs

  • 이미 μˆ¨λ°”κΌ­μ§ˆ 1κ³Ό 3을 ν’€μ–΄μ„œ λŒ€μΆ© μ•Œκ³  μžˆλ‹€. x - 1, x + 1, x * 2 큐에 λ„£μ–΄μ£Όλ©΄μ„œ νƒμƒ‰ν•˜λ©΄ 됨.
  • 경우의 수λ₯Ό μ–΄λ–»κ²Œ ꡬ할지 μƒκ°λ§Œ ν•˜λ©΄ λœλ‹€.

2. 경우의 수

  • μ­‰ 탐색을 ν•˜λ‹€κ°€ 맨 처음 λ™μƒν•œν…Œ λ„μ°©ν•œ μ‹œκ°„μ„ μ €μž₯ν•˜κ³ 
  • 이후 λ™μƒν•œν…Œ λ„μ°©ν–ˆμ„ λ•Œ μ €μž₯ν•΄λ‘” μ‹œκ°„κ³Ό κ°™λ‹€λ©΄ 경우의 수λ₯Ό +1 ν•΄μ€€λ‹€.

전체 μ½”λ“œ

from collections import deque
N, K = map(int,input().split())
visited = [0] * 200001


def bfs(n):
    ans_count = 100001
    ans_way = 0

    deq = deque()
    deq.append([n, 0])
    visited[n] = 0

    while deq:
        x, count = deq.popleft()

        if count > ans_count:
            continue

        if x == K:
            if ans_count == 100001:
                ans_count = count

            if count == ans_count:
                ans_way += 1

        arr = [x - 1, x + 1, x * 2]

        for a in arr:
            if 0 <= a <= 200000 and (visited[a] == 0 or visited[a] == count + 1):
                visited[a] = count + 1
                deq.append([a,count + 1])

    return ans_count, ans_way

for ans in bfs(N):
    print(ans)

μ½”λ“œ μ„€λͺ…

def bfs(n):
    ans_count = 100001
    ans_way = 0

    deq = deque()
    deq.append([n, 0])
    visited[n] = 0

    while deq:
        x, count = deq.popleft()

        if count > ans_count:
            continue

        if x == K:
            if ans_count == 100001:
                ans_count = count

            if count == ans_count:
                ans_way += 1

        arr = [x - 1, x + 1, x * 2]

        for a in arr:
            if 0 <= a <= 200000 and (visited[a] == 0 or visited[a] == count + 1):
                visited[a] = count + 1
                deq.append([a,count + 1])

    return ans_count, ans_way

λ¨Όμ € λ°©λ²•μ˜ 수λ₯Ό μ €μž₯ν•  ans_wayλ³€μˆ˜μ™€ μ΅œλ‹¨ μ‹œκ°„μ„ μ €μž₯ν•  ans_countλ₯Ό μ„ μ–Έν•΄μ€€λ‹€.

ans_countλŠ” 100000 0 μž…λ ₯이 듀어왔을 λ•Œ λ‚˜μ˜€λŠ” μ‹œκ°„(100000) 보닀 크게 μ„€μ •(100001)

그리고 visited리슀트λ₯Ό boolean λ¦¬μŠ€νŠΈκ°€ μ•„λ‹Œ int 리슀트둜 μ„ μ–Έν•œλ‹€. λ‚˜μ€‘μ— μ‚¬μš©ν•¨.

 

기본적인 틀은 κ°„λ‹¨ν•˜λ‹€.

큐에 x + 1, x - 1, x * 2κ°€ 쑰건에 μΆ©μ‘±ν•˜λ©΄ 큐에 λ„£κ³  νƒμƒ‰ν•˜λŠ” 방법이닀.

주어진 λ²”μœ„μ—μ„œ 방문을 ν•˜μ§€ μ•Šμ•˜κ±°λ‚˜, μ•„λ‹ˆλ©΄ κ·Έ μœ„μΉ˜μ— μ΅œλ‹¨μ‹œκ°„μœΌλ‘œ λ°©λ¬Έν•œ 경우 큐에 μΆ”κ°€ν•΄μ€€λ‹€.

 

μ™œ λ°©λ¬Έ 유무만 λ”°μ§€λŠ” 게 μ•„λ‹ˆλƒλ©΄, 예λ₯Ό λ“€μ–΄ 1 3으둜 μž…λ ₯이 λ“€μ–΄μ™”λ‹€κ³  치면

1 2 3(+1 +1)

1 2 3(*2 +1) 

μ΄λ ‡κ²Œ 총 2가지 κ²½μš°κ°€ λ‚˜μ˜¨λ‹€. *2와 +1 은 λ‹€λ₯Έ κ²½μš°μ΄λ―€λ‘œ 이λ₯Ό κ΅¬λΆ„ν•΄μ€˜μ•Ό 함.

 

탐색을 ν•˜λ‹€ 보면 졜초둜 λ™μƒμ—κ²Œ λ„μ°©ν•˜λŠ” κ²½μš°κ°€ 생길 κ±°λ‹€.

그럼 μ΄λ•Œ(if x == K 일 λ•Œ) ans_count에 값을 μ—…λ°μ΄νŠΈν•˜κ³  ans_way값을 1 μ¦κ°€μ‹œμΌœμ€€λ‹€.

μ΄ν›„μ—λŠ” ans_count 값이 count와 κ°™μœΌλ©΄ ans_way값을 1 μ¦κ°€μ‹œμΌœμ€€λ‹€.

 

이 문제λ₯Ό ν’€λ©΄μ„œ 정말 많이 ν‹€λ Έλ‹€. ν’€λ©΄μ„œ λŠλ‚€ 건 엣지 μΌ€μ΄μŠ€λŠ” 무쑰건 해보고 μ œμΆœν•˜κΈ°.