Algorithm

[λ°±μ€€] 2206. λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ° python

🐳 링크

λ°±μ€€ λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ°

πŸ• 문제

NΓ—M의 ν–‰λ ¬λ‘œ ν‘œν˜„λ˜λŠ” 맡이 μžˆλ‹€. λ§΅μ—μ„œ 0은 이동할 수 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚΄κ³ , 1은 이동할 수 μ—†λŠ” 벽이 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚Έλ‹€. 당신은 (1, 1)μ—μ„œ (N, M)의 μœ„μΉ˜κΉŒμ§€ μ΄λ™ν•˜λ € ν•˜λŠ”λ°, μ΄λ•Œ μ΅œλ‹¨ 경둜둜 μ΄λ™ν•˜λ € ν•œλ‹€. μ΅œλ‹¨κ²½λ‘œλŠ” λ§΅μ—μ„œ κ°€μž₯ 적은 개수의 칸을 μ§€λ‚˜λŠ” 경둜λ₯Ό λ§ν•˜λŠ”λ°, μ΄λ•Œ μ‹œμž‘ν•˜λŠ” μΉΈκ³Ό λλ‚˜λŠ” 칸도 ν¬ν•¨ν•΄μ„œ μ„Όλ‹€.

λ§Œμ•½μ— μ΄λ™ν•˜λŠ” 도쀑에 ν•œ 개의 벽을 λΆ€μˆ˜κ³  μ΄λ™ν•˜λŠ” 것이 μ’€ 더 κ²½λ‘œκ°€ 짧아진닀면, 벽을 ν•œ 개 κΉŒμ§€ λΆ€μˆ˜κ³  μ΄λ™ν•˜μ—¬λ„ λœλ‹€.

맡이 μ£Όμ–΄μ‘Œμ„ λ•Œ, μ΅œλ‹¨ 경둜λ₯Ό ꡬ해 λ‚΄λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

🐾 풀이 방법

bfsλ¬Έμ œμ— 벽을 λΆ€μˆ˜λŠ” 쑰건이 μΆ”κ°€λœ λ¬Έμ œμ΄λ‹€.
λ°©λ¬Έν–ˆλ‹€λŠ” 것을 ν™•μΈν•˜κΈ° μœ„ν•œ visit 배열을 λ‹¨μˆœνžˆ [0] 이 μ•„λ‹Œ [0,0]κ³Ό 같이 λ‚˜νƒ€λ‚΄μ–΄ [0]λ²ˆμ§Έμ—λŠ” 무쑰건 벽을 λΆ€μˆœ κ²½μš°κ°€ 듀어가도둝 μ„€μ •ν•œλ‹€.

특히 μ²˜μŒμ— queue에 값을 μ‚½μž…ν•  λ•Œ, ν˜„μž¬ μœ„μΉ˜λ₯Ό λ‚˜νƒ€λ‚΄λŠ” (x,y)에 breakCount 즉 벽을 λΆ€μˆ  수 μžˆλŠ” κ°€μ§“μˆ˜μΈ 1을 ν•¨κ»˜ λ„£μ–΄ (x,y,breakCount)와 같이 λ°›λŠ”λ‹€. 이후 벽을 λΆ€μˆœ κ²½μš°μ—λŠ” breakCount = 0이 λ˜λ„λ‘ ν•œλ‹€..!

λ”°λΌμ„œ x,y,breakCount λ₯Ό queueμ—μ„œ λΉΌλ‚Έ λ’€, Map이 벽이고 breakCountκ°€ 1인 κ²½μš°μ—λŠ” 벽을 λΆ€μˆ˜κ³  μ§€λ‚˜κ°€λ„λ‘ ν•˜κ³ , visit배열을 μ—…λ°μ΄νŠΈ ν•΄ μ€€λ‹€.

였늘 ν‘Ό 문제 λͺ¨λ‘ 풀이λ₯Ό νš‘μ„€μˆ˜μ„€ν•˜λŠ” κΈ°λΆ„...

κΆκΈˆν•œ 점🧐

ν•˜μ§€λ§Œ 맀우 κΆκΈˆν•œ 점이 μžˆλ‹€.
μ•„λž˜ 두 μ†ŒμŠ€μ½”λ“œλ₯Ό 보면 μ•Œκ² μ§€λ§Œ, bfs 과정을 ν•¨μˆ˜ν™”ν•œ 것과 그렇지 μ•Šμ€ 것 두가지인데, ν•¨μˆ˜ν™”ν•œ κ²½μš°μ—λŠ” python3μ—μ„œ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚˜μ§€ μ•Šκ³  ν•¨μˆ˜ν™”ν•˜μ§€ μ•Šμ€ κ²½μš°μ—λŠ” python3μ—μ„œ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚œλ‹€.
κ·Έλž˜μ„œ ν•¨μˆ˜ν™”ν•˜μ§€ μ•Šμ€ κ²½μš°μ—

  • Map을 받을 λ•Œ mapν•¨μˆ˜λ₯Ό 톡해 int둜 λ³€ν™˜μ‹œν‚€λŠ” μ½”λ“œλ‘œ λ³€κ²½ν•˜κΈ°
  • Map == 1κ³Ό Map == 0 뢀뢄을 if-elif ꡬ문으둜 λ³€κ²½ν•˜κΈ°
    λ“±λ“±μœΌλ‘œ λ³€κ²½ν•΄λ³΄μ•˜μ§€λ§Œ μ—¬μ „νžˆ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚˜κ³ , μ½”λ“œλŠ” 아무 λ³€κ²½ 없이 ν•¨μˆ˜ν™”μ‹œν‚€λ©΄ λ°”λ‘œ passκ°€ λ‚˜μ™”λ‹€.

λ„μ €νžˆ λͺ¨λ₯΄κ² μ–΄μ„œ time νŒ¨ν‚€μ§€λ₯Ό ν™œμš©ν•˜μ—¬ time.perf_counter()둜 μ‹œκ°„ 츑정을 ν•΄ λ³΄μ•˜λŠ”λ°, μ•„λž˜ μ˜ˆμ œμ— λŒ€ν•΄μ„œλŠ” 심지어 ν•¨μˆ˜ν™”ν•˜μ§€ μ•Šμ€ μ½”λ“œκ°€ 더 λΉ¨λžλ‹€..

6 4
0100
1110
1000
0000
0111
0000

ν•¨μˆ˜ν™” μ½”λ“œ: 0.0009308000000000094
ν•¨μˆ˜ν™”ν•˜μ§€ μ•Šμ€ μ½”λ“œ: 0.0007831999999999978
λ„λŒ€μ²΄ 무슨 이유일까?!?!?!?!?

μ†ŒμŠ€μ½”λ“œ

python3으둜 ν–ˆμ„ λ•Œ ν†΅κ³Όν•œ μ½”λ“œ

import sys
n, m = map(int, sys.stdin.readline().split())
Map = list()
for _ in range(n):
    temp = sys.stdin.readline().strip()
    temp = list(map(lambda x: int(x), temp))
    Map.append(temp)


dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]

def bfs():
    queue = [(0, 0, 1)]
    visit = [[[0] * 2 for i in range(m)] for i in range(n)]
    visit[0][0][1] = 1

    while queue:
        x, y, breakCount = queue.pop(0)
        if x == n - 1 and y == m - 1:
            return visit[x][y][breakCount]


        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if Map[nx][ny] == 0 and visit[nx][ny][breakCount] == 0:
                    queue.append((nx, ny, breakCount))
                    visit[nx][ny][breakCount] = visit[x][y][breakCount] + 1
                if Map[nx][ny] == 1 and breakCount == 1:  # 벽이고, 벽을 λΆ€μˆ˜μ§€ μ•Šμ€ 경우
                    queue.append((nx, ny, 0))
                    visit[nx][ny][0] = visit[x][y][1] + 1
    return -1

print(bfs())

python3으둜 ν•˜λ©΄ μ‹œκ°„μ΄ˆκ³Ό, Pypy3으둜 ν•˜λ©΄ 톡과

import sys

n, m = map(int, sys.stdin.readline().split())
Map = list()
for _ in range(n):
    temp = sys.stdin.readline().strip()
    temp = list(map(lambda x: int(x), temp))
    Map.append(temp)

queue = [(0, 0, 1)]
visit = [[[0] * 2 for i in range(m)] for i in range(n)]
visit[0][0][1] = 1
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
count = -1

while queue:
    x, y, breakCount = queue.pop(0)
    if x == n - 1 and y == m - 1:
        count = visit[x][y][breakCount]
        break

    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]
        if 0 <= nx < n and 0 <= ny < m:
            if Map[nx][ny] == 0 and visit[nx][ny][breakCount] == 0:
                queue.append((nx, ny, breakCount))
                visit[nx][ny][breakCount] = visit[x][y][breakCount] + 1
            if Map[nx][ny] == 1 and breakCount == 1:  # 벽이고, 벽을 λΆ€μˆ˜μ§€ μ•Šμ€ 경우
                queue.append((nx, ny, 0))
                visit[nx][ny][0] = visit[x][y][1] + 1

print(count)