λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Coding Test/Algorithms

[λ°±μ€€] 2206. λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ°/Python - Gold 3

by The Future Engineer, Lucy 2025. 2. 12.
728x90
λ°˜μ‘ν˜•

β“λ¬Έμ œ

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

μ„±λŠ₯ μš”μ•½

λ©”λͺ¨λ¦¬: 323464 KB, μ‹œκ°„: 1936 ms

λΆ„λ₯˜

λ„ˆλΉ„ μš°μ„  탐색, κ·Έλž˜ν”„ 이둠, κ·Έλž˜ν”„ 탐색

 

문제 μ„€λͺ…

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

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

ν•œ μΉΈμ—μ„œ 이동할 수 μžˆλŠ” 칸은 μƒν•˜μ’Œμš°λ‘œ μΈμ ‘ν•œ 칸이닀.

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

βœπŸ»ν’€μ΄

μ΄λ™ν•˜λ©΄μ„œ 벽을 ν•œ κ°œλŠ” λΆ€μˆ  수 μžˆλ‹€κ³  ν•œλ‹€. 그러면 μš°λ¦¬λŠ” 벽을 λΆ€μ‰ˆλŠ”μ§€ μ•ˆ λΆ€μ‰ˆλŠ”μ§€λ₯Ό 기둝해야 ν•œλ‹€. κ·Έλž˜μ„œ λ‚˜λŠ” μ²˜μŒμ— 이동할 λ•Œ 벽을 λΆ€μ‰ˆλŠ”μ§€ μ•ˆ λΆ€μ‰ˆλŠ”μ§€μ— λŒ€ν•΄ νμ—λ§Œ κΈ°λ‘ν•˜μ—¬ ν‹€λ Έλ‹€.

μš°λ¦¬λŠ” 이동할 λ•Œ 벽을 λΆ€μˆ˜κ³  갈 μˆ˜λ„ 있고 λΆ€μˆ˜κ³  가지 μ•Šμ„ μˆ˜λ„ μžˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ λΆ€μˆ˜κ³  κ°€λŠ” κ²½μš°μ™€ λΆ€μˆ˜μ§€ μ•Šκ³  κ°€λŠ” 경우λ₯Ό λ‚˜λˆ μ„œ visited 배열을 3차원 λ°°μ—΄λ‘œ ν•˜μ—¬ κΈ°λ‘ν–ˆλ‹€. visited[y][x][0]은 벽을 λΆ€μˆ˜κ³  가지 μ•Šκ³  μ΄λ™ν•œ 횟수λ₯Ό λ‚˜νƒ€λ‚΄κ³ , visited[y][x][1]은 λΆ€μˆ˜κ³  μ΄λ™ν•œ 횟수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

λ§Œμ•½ λ‹€μŒ μœ„μΉ˜κ°€ 1이고 아직 λΆ€μˆœ 적이 μ—†λ‹€λ©΄ visted[ny][nx][1] = visited[cy][cx][0] + 1을 ν•˜μ—¬ κΈ°λ‘ν•œλ‹€. 그렇지 μ•Šκ³  λ‹€μŒ μœ„μΉ˜κ°€ 0이고 아직 λ°©λ¬Έν•œ 적 μ—†λŠ” 곳이라면 visited[ny][nx][crack] = visited[cy][cx][crack] + 1을 ν•˜μ—¬ κΈ°λ‘ν•˜λ©΄ λœλ‹€. μ—¬κΈ°μ„œ crack은 벽을 λΆ€μ‰ˆλŠ”μ§€ λΆ€μˆ˜μ§€ μ•Šμ•˜λŠ”μ§€λ₯Ό μ˜λ―Έν•œλ‹€.

이 같은 λ°©λ²•μœΌλ‘œ 기둝을 ν•˜μ—¬ ν˜„μž¬ μœ„μΉ˜κ°€ (N-1, M-1)이라면 visited[N-1][M-1][crack]을 λ°˜ν™˜ν•˜λ©΄ 되고, 그렇지 μ•Šλ‹€λ©΄ -1을 λ°˜ν™˜ν•˜λ©΄ λœλ‹€.

πŸ’»μ½”λ“œ

ν‹€λ¦° μ½”λ“œ

import sys
from collections import deque

input = sys.stdin.readline

N, M = map(int, input().split())
graph = [list(input().strip()) for _ in range(N)]
visited = [[False for _ in range(M)] for _ in range(N)]
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]

def bfs():
    q = deque()
    q.append((0, 0, False))
    visited[0][0] = True
    cnt = 0

    while q:
        ln = len(q)
        for _ in range(ln):
            cy, cx, crack = q.popleft()

            if (cy, cx) == (N-1, M-1):
                print(cnt + 1)
                return

            for i in range(4):
                ny, nx = cy + dy[i], cx + dx[i]

                if 0 <= ny < N and 0 <= nx < M:
                    if not visited[ny][nx] and graph[ny][nx] == "0":
                        visited[ny][nx] = True
                        q.append((ny, nx, crack))

                    if graph[ny][nx] == "1" and not crack:
                        q.append((ny, nx, True))

        cnt += 1

    print(-1)

bfs()

μ •λ‹΅ μ½”λ“œ

import sys
from collections import deque

input = sys.stdin.readline

N, M = map(int, input().split())
graph = [list(input().strip()) for _ in range(N)]
visited = [[[0, 0] for _ in range(M)] for _ in range(N)]
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]

def bfs():
    q = deque()
    q.append((0, 0, 0))
    visited[0][0][0] = 1

    while q:
        cy, cx, crack = q.popleft()

        if (cy, cx) == (N-1, M-1):
            return visited[cy][cx][crack]

        for i in range(4):
            ny, nx = cy + dy[i], cx + dx[i]

            if 0 <= ny < N and 0 <= nx < M:
                if not visited[ny][nx][crack] and graph[ny][nx] == "0":
                    visited[ny][nx][crack] = visited[cy][cx][crack] + 1
                    q.append((ny, nx, crack))

                if graph[ny][nx] == "1" and crack == 0:
                    visited[ny][nx][1] = visited[cy][cx][0] + 1
                    q.append((ny, nx, 1))

    return -1

print(bfs())

πŸ“ν›„κΈ°

μ²˜μŒμ—λŠ” κ·Έλƒ₯ νμ—λ§Œ λΆ€μ‰ˆλŠ”μ§€ μ•ˆ λΆ€μ‰ˆλŠ”μ§€ κΈ°λ‘ν•˜λ©΄ λœλ‹€κ³  μƒκ°ν–ˆλ‹€. 그런데 μƒκ°ν•΄λ³΄λ‹ˆ λ„λ‹¬ν•˜λŠ” μœ„μΉ˜λ₯Ό 벽을 λΆ€μˆ˜κ³  λ„λ‹¬ν–ˆμ„ μˆ˜λ„ 있고 그렇지 μ•Šμ„ μˆ˜λ„ μžˆλ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜λ‹€. 문제λ₯Ό ν’€ λ•Œ λ„ˆλ¬΄ λ‹¨μˆœν•˜κ²Œ μƒκ°ν•˜μ§€ 말아야 κ² λ‹€.

그리고 ν‰μ†Œμ— λ³€μˆ˜λ₯Ό λ”°λ‘œ λ§Œλ“€μ–΄μ„œ 이동 횟수λ₯Ό κΈ°λ‘ν•˜λ €κ³  ν–ˆλŠ”λ° μƒκ°ν•΄λ³΄λ‹ˆ visited에 μ €μž₯해도 됐닀. 괜히 λ³€μˆ˜ ν•˜λ‚˜ 더 λ§Œλ“€μ–΄μ„œ λ©”λͺ¨λ¦¬λ₯Ό λŠ˜λ¦¬μ§€ μ•Šλ„λ‘ 해야지...

728x90
λ°˜μ‘ν˜•