[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ์•„์ดํ…œ์ค๊ธฐ (Python, Graph, BFS)

    ๋ฐ˜์‘ํ˜•

    ๐Ÿ’ก๋ฌธ์ œ

    ๋ฌธ์ œ ๋งํฌ: https://school.programmers.co.kr/learn/courses/30/lessons/87694

     

    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

    ์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

    programmers.co.kr

     

    ๋ฌธ์ œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ์‚ฌ๊ฐํ˜• ์ •๋ณด(์ขŒํ•˜๋‹จ ์ขŒํ‘œ์™€ ์šฐ์ƒ๋‹จ ์ขŒํ‘œ)๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ ํ…Œ๋‘๋ฆฌ๋ฅผ ๋”ฐ๋ผ ๋‹ค๊ฐํ˜• ๋ชจ์–‘ ์ง€ํ˜•์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ๊ทธ ์œ„์— ์บ๋ฆญํ„ฐ์˜ ์œ„์น˜์™€ ์•„์ดํ…œ์˜ ์œ„์น˜๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ ์•„์ดํ…œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

     

    ๐Ÿ’กํ’€์ด

    ๋ฌธ์ œ๋ฅผ ํ’€๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‘๊ฐ€์ง€ ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

    1. ํ…Œ๋‘๋ฆฌ๋ฅผ ๋”ฐ๋ผ ๊ฒŒ์ž„ ๋งต์„ ๋งŒ๋“ค์–ด์•ผํ•˜๊ณ ,
    2. ๊ทธ ํ…Œ๋‘๋ฆฌ๋ฅผ ๋”ฐ๋ผ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    ์ €๋Š” ํ…Œ๋‘๋ฆฌ๋ฅผ ๋”ฐ๋ผ์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ ์ „ํ˜•์ ์ธ BFS ๋ฌธ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ํ’€ ์ˆ˜ ์žˆ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์ฒซ๋ฒˆ์งธ ๊ณผ์ •, ์ฆ‰ ํ…Œ๋‘๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์—์„œ ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ œ๊ฐ€ ๊ฒช์€ ์‹œํ–‰์ฐฉ์˜ค ๊ณผ์ •์„ ๊ทธ๋Œ€๋กœ ์ž‘์„ฑํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

    ์ฒซ๋ฒˆ์งธ๋กœ ์ œ๊ฐ€ ์ƒ๊ฐํ•œ ๊ฒƒ์€ ๋ฌธ์ œ์—์„œ ์ค€ ๊ทธ๋Œ€๋กœ "๊ตฌํ˜„"ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ์„  ๋ฌธ์ œ์—์„œ ๊ฐ€๋กœ ์„ธ๋กœ ์ตœ๋Œ€๊ฐ€ 50์ด๋ผ๊ณ  ์ฃผ์—ˆ์œผ๋‹ˆ -1๋กœ ์ฑ„์›Œ์ง„ 2์ฐจ์› ๋ฆฌ์ŠคํŠธ๋ฅผ ๋จผ์ € ๋งŒ๋“ค์–ด๋†“๊ณ , ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ์‚ฌ๊ฐํ˜• ์ •๋ณด๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ
    ํ…Œ๋‘๋ฆฌ๋Š” 1, ๋‚ด๋ถ€๋Š” 0์œผ๋กœ ์ฑ„์› ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์‚ฌ๊ฐํ˜•์˜ ํ…Œ๋‘๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๊ฐํ˜•์˜ ๋‚ด๋ถ€์™€ ๊ฒน์น˜๋ฉด 0(๋‚ด๋ถ€)๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋‹ค๊ฐํ˜•์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    field = [[-1] * 51 for _ in range(51)]
    
    for rectangle in rectangles:
        x1, y1, x2, y2 = rectangle
    
        for i in range(x1, x2 + 1):
            for j in range(y1, y2 + 1):
                if x1 < i < x2 and y1 < j < y2: # ์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€
                    field[i][j] = 0
                elif field[i][j] == 0: # ํ…Œ๋‘๋ฆฌ์ธ๋ฐ, ์ด๋ฏธ ๋‹ค๋ฅธ ์‚ฌ๊ฐํ˜•์˜ ๋‚ด๋ถ€์ธ ๊ฒฝ์šฐ
                    field[i][j] = 0
                else: # ํ…Œ๋‘๋ฆฌ
                    field[i][j] = 1

     

    ์œ„์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ž…์ถœ๋ ฅ์˜ˆ์ œ 1๋ฒˆ์˜ field๋ฅผ printํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. (ํŽธ์˜์ƒ ์ „์ฒด ๋งต์˜ ํฌ๊ธฐ๋ฅผ 20x20์œผ๋กœ ์ค„์˜€์Šต๋‹ˆ๋‹ค.)

    ์ด๋ ‡๊ฒŒ ๋ฝ‘์•„๋†“๊ณ  ๋ณด๋‹ˆ '์˜ค ๋ฌธ์ œ์—์„œ ํ…Œ๋‘๋ฆฌ๋ฅผ ๊ทธ๋ฆฐ๊ฒƒ์ฒ˜๋Ÿผ ๋˜‘๊ฐ™์ด ๋‚˜์˜ค๋‹ˆ๊นŒ ์ด์ œ BFS๋กœ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๊ตฌํ•˜๋ฉด๋˜๊ฒ ๋‹ค!' ํ•˜๊ณ  ๋ฐ”๋กœ BFS๋กœ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•ด๋ณด์•˜๋”๋‹ˆ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ๋นจ๊ฐ„์ƒ‰ ๋ถ€๋ถ„์ด ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

    ํ˜•๊ด‘์ƒ‰์„ ๋”ฐ๋ผ์„œ ์›€์ง์—ฌ์•ผํ–๋Š”๋ฐ, BFS์—์„œ ์ƒํ•˜์ขŒ์šฐ๋ฅผ ๋ชจ๋‘ ํƒ์ƒ‰ํ•˜๋‹ค๋ณด๋‹ˆ ํ…Œ๋‘๋ฆฌ๋กœ ์ด์–ด์ง€์ง€ ์•Š์ง€๋งŒ ์ธ์ ‘ํ•ด์žˆ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๋ฐ”๋กœ ๋„˜์–ด๊ฐ€์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๊ฐ€ ์ž˜๋ชป ๊ณ„์‚ฐ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

     

    ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์ € ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„์„ ๋–จ์–ด๋œจ๋ ค๋†“๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ๋”ฐ๋ผ์„œ ๊ฒŒ์ž„ ๋งต ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋กœ ๋Š˜๋ฆฌ๊ณ  ์‚ฌ๊ฐํ˜•๋„ ๋‘๋ฐฐ๋กœ ๋Š˜๋ ธ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ๋ฌธ์ œ๊ฐ€ ๋˜์—ˆ๋˜ ๋ถ€๋ถ„์ด ๋–จ์–ด์ง€๊ฒŒ ๋˜๋ฉด์„œ ์ •ํ™•ํ•˜๊ฒŒ ํ…Œ๋‘๋ฆฌ๋งŒ์„ ๋”ฐ๋ผ์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

     

    ๐Ÿ’ก์ •๋‹ต ์ฝ”๋“œ

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # programmers ์•„์ดํ…œ ์ค๊ธฐ
    
    from collections import deque
    
    
    def solution(rectangles, characterX, characterY, itemX, itemY):
        answer = 0
        routes = []
    
        field = [[-1] * 102 for _ in range(20)]
    
        for rectangle in rectangles:
            x1, y1, x2, y2 = map(lambda x: x * 2, rectangle)
    
            for i in range(x1, x2 + 1):
                for j in range(y1, y2 + 1):
                    if x1 < i < x2 and y1 < j < y2:
                        field[i][j] = 0
                    elif field[i][j] == 0:
                        field[i][j] = 0
                    else:
                        field[i][j] = 1
    
        character = (characterX * 2, characterY * 2)
        item = (itemX, itemY)
        visited = [[False] * 102 for _ in range(102)]
        queue = deque([character])
        visited[characterX * 2][characterY * 2] = True
        dx, dy = [0, 0, -1, 1], [-1, 1, 0, 0]
    
        while queue:
            x, y = queue.popleft()
            for i in range(4):
                nx, ny = x + dx[i], y + dy[i]
                if field[nx][ny] == 1 and not visited[nx][ny]:
                    queue.append((nx, ny))
                    visited[nx][ny] = True
                    field[nx][ny] = field[x][y] + 1
    
        return field[itemX * 2][itemY * 2] // 2
    
    
    rectangles = [[1, 1, 7, 4], [3, 2, 5, 5], [4, 3, 6, 9], [2, 6, 8, 8]]
    characterX, characterY, itemX, itemY = 1, 3, 7, 8
    print(solution(rectangles, characterX, characterY, itemX, itemY))
    • ๊ฐ€๋กœ์™€ ์„ธ๋กœ๊ฐ€ ๋ชจ๋‘ ์ตœ๋Œ€ 50์ด๋ฏ€๋กœ field๋Š” 102x102๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (51 * 2)
    • ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ์‚ฌ๊ฐํ˜•์˜ ์ •๋ณด(rectangle)๋ฅผ ๋ชจ๋‘ 2๋ฐฐ๋กœ ํ•˜์—ฌ field๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
    • character์˜ ์œ„์น˜๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 2๋ฐฐ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.
    • ๋ฐฉ๋ฌธํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฆฌ์ŠคํŠธ(visited)์™€ queue๋ฅผ ๋งŒ๋“ค์–ด์„œ BFS ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
    • field[itemX * 2][itemY * 2]์— ์ €์žฅ๋œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ 2๋กœ ๋‚˜๋ˆ„์–ด ์›๋ž˜์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.
    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€