Algorithm

[๋ฐฑ์ค€] 16236. ์•„๊ธฐ ์ƒ์–ด python

๐Ÿณ ๋งํฌ

๋ฐฑ์ค€ ์•„๊ธฐ์ƒ์–ด

๐Ÿ• ๋ฌธ์ œ

Nร—N ํฌ๊ธฐ์˜ ๊ณต๊ฐ„์— ๋ฌผ๊ณ ๊ธฐ M๋งˆ๋ฆฌ์™€ ์•„๊ธฐ ์ƒ์–ด 1๋งˆ๋ฆฌ๊ฐ€ ์žˆ๋‹ค. ๊ณต๊ฐ„์€ 1ร—1 ํฌ๊ธฐ์˜ ์ •์‚ฌ๊ฐํ˜• ์นธ์œผ๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๋‹ค. ํ•œ ์นธ์—๋Š” ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์ตœ๋Œ€ 1๋งˆ๋ฆฌ ์กด์žฌํ•œ๋‹ค.

์•„๊ธฐ ์ƒ์–ด์™€ ๋ฌผ๊ณ ๊ธฐ๋Š” ๋ชจ๋‘ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด ํฌ๊ธฐ๋Š” ์ž์—ฐ์ˆ˜์ด๋‹ค. ๊ฐ€์žฅ ์ฒ˜์Œ์— ์•„๊ธฐ ์ƒ์–ด์˜ ํฌ๊ธฐ๋Š” 2์ด๊ณ , ์•„๊ธฐ ์ƒ์–ด๋Š” 1์ดˆ์— ์ƒํ•˜์ขŒ์šฐ๋กœ ์ธ์ ‘ํ•œ ํ•œ ์นธ์”ฉ ์ด๋™ํ•œ๋‹ค.

์•„๊ธฐ ์ƒ์–ด๋Š” ์ž์‹ ์˜ ํฌ๊ธฐ๋ณด๋‹ค ํฐ ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์žˆ๋Š” ์นธ์€ ์ง€๋‚˜๊ฐˆ ์ˆ˜ ์—†๊ณ , ๋‚˜๋จธ์ง€ ์นธ์€ ๋ชจ๋‘ ์ง€๋‚˜๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์•„๊ธฐ ์ƒ์–ด๋Š” ์ž์‹ ์˜ ํฌ๊ธฐ๋ณด๋‹ค ์ž‘์€ ๋ฌผ๊ณ ๊ธฐ๋งŒ ๋จน์„ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํฌ๊ธฐ๊ฐ€ ๊ฐ™์€ ๋ฌผ๊ณ ๊ธฐ๋Š” ๋จน์„ ์ˆ˜ ์—†์ง€๋งŒ, ๊ทธ ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์žˆ๋Š” ์นธ์€ ์ง€๋‚˜๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

์•„๊ธฐ ์ƒ์–ด๊ฐ€ ์–ด๋””๋กœ ์ด๋™ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๋” ์ด์ƒ ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ๊ณต๊ฐ„์— ์—†๋‹ค๋ฉด ์•„๊ธฐ ์ƒ์–ด๋Š” ์—„๋งˆ ์ƒ์–ด์—๊ฒŒ ๋„์›€์„ ์š”์ฒญํ•œ๋‹ค.
๋จน์„ ์ˆ˜ ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ๊ฐ€ 1๋งˆ๋ฆฌ๋ผ๋ฉด, ๊ทธ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์œผ๋Ÿฌ ๊ฐ„๋‹ค.
๋จน์„ ์ˆ˜ ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ๊ฐ€ 1๋งˆ๋ฆฌ๋ณด๋‹ค ๋งŽ๋‹ค๋ฉด, ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์œผ๋Ÿฌ ๊ฐ„๋‹ค.
๊ฑฐ๋ฆฌ๋Š” ์•„๊ธฐ ์ƒ์–ด๊ฐ€ ์žˆ๋Š” ์นธ์—์„œ ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์žˆ๋Š” ์นธ์œผ๋กœ ์ด๋™ํ•  ๋•Œ, ์ง€๋‚˜์•ผํ•˜๋Š” ์นธ์˜ ๊ฐœ์ˆ˜์˜ ์ตœ์†Ÿ๊ฐ’์ด๋‹ค.
๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€๊นŒ์šด ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ๋งŽ๋‹ค๋ฉด, ๊ฐ€์žฅ ์œ„์— ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ, ๊ทธ๋Ÿฌํ•œ ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์—ฌ๋Ÿฌ๋งˆ๋ฆฌ๋ผ๋ฉด, ๊ฐ€์žฅ ์™ผ์ชฝ์— ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน๋Š”๋‹ค.
์•„๊ธฐ ์ƒ์–ด์˜ ์ด๋™์€ 1์ดˆ ๊ฑธ๋ฆฌ๊ณ , ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน๋Š”๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์€ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. ์ฆ‰, ์•„๊ธฐ ์ƒ์–ด๊ฐ€ ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์žˆ๋Š” ์นธ์œผ๋กœ ์ด๋™ํ–ˆ๋‹ค๋ฉด, ์ด๋™๊ณผ ๋™์‹œ์— ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน๋Š”๋‹ค. ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์œผ๋ฉด, ๊ทธ ์นธ์€ ๋นˆ ์นธ์ด ๋œ๋‹ค.

์•„๊ธฐ ์ƒ์–ด๋Š” ์ž์‹ ์˜ ํฌ๊ธฐ์™€ ๊ฐ™์€ ์ˆ˜์˜ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์„ ๋•Œ ๋งˆ๋‹ค ํฌ๊ธฐ๊ฐ€ 1 ์ฆ๊ฐ€ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํฌ๊ธฐ๊ฐ€ 2์ธ ์•„๊ธฐ ์ƒ์–ด๋Š” ๋ฌผ๊ณ ๊ธฐ๋ฅผ 2๋งˆ๋ฆฌ ๋จน์œผ๋ฉด ํฌ๊ธฐ๊ฐ€ 3์ด ๋œ๋‹ค.

๊ณต๊ฐ„์˜ ์ƒํƒœ๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ์•„๊ธฐ ์ƒ์–ด๊ฐ€ ๋ช‡ ์ดˆ ๋™์•ˆ ์—„๋งˆ ์ƒ์–ด์—๊ฒŒ ๋„์›€์„ ์š”์ฒญํ•˜์ง€ ์•Š๊ณ  ๋ฌผ๊ณ ๊ธฐ๋ฅผ ์žก์•„๋จน์„ ์ˆ˜ ์žˆ๋Š”์ง€ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ž…๋ ฅ

์ฒซ์งธ ์ค„์— ๊ณต๊ฐ„์˜ ํฌ๊ธฐ N(2 โ‰ค N โ‰ค 20)์ด ์ฃผ์–ด์ง„๋‹ค.

๋‘˜์งธ ์ค„๋ถ€ํ„ฐ N๊ฐœ์˜ ์ค„์— ๊ณต๊ฐ„์˜ ์ƒํƒœ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ณต๊ฐ„์˜ ์ƒํƒœ๋Š” 0, 1, 2, 3, 4, 5, 6, 9๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ณ , ์•„๋ž˜์™€ ๊ฐ™์€ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

0: ๋นˆ ์นธ
1, 2, 3, 4, 5, 6: ์นธ์— ์žˆ๋Š” ๋ฌผ๊ณ ๊ธฐ์˜ ํฌ๊ธฐ
9: ์•„๊ธฐ ์ƒ์–ด์˜ ์œ„์น˜
์•„๊ธฐ ์ƒ์–ด๋Š” ๊ณต๊ฐ„์— ํ•œ ๋งˆ๋ฆฌ ์žˆ๋‹ค.

๐Ÿพ ํ’€์ด ๋ฐฉ๋ฒ•

https://dailyheumsi.tistory.com/59
์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, dfs๋ฅผ ์ด์šฉํ•˜๊ณ  ํ’€์—ˆ๋Š”๋ฐ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์œ„ ํ‹ฐ์Šคํ† ๋ฆฌ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค... ใ… ใ… 

๋ชจ๋“  ํ…Œ์ŠคํŠธ์ผ€์ด์Šค ์„ฑ๊ณต ์ฝ”๋“œ

from collections import deque
import sys
sys.stdin = open("input.txt", "rt")
dx = [-1,0,0,1]
dy = [0,-1,1,0]

def bfs(_x,_y):
    q, visited = deque([(_x,_y)]), set([(_x,_y)])
    seconds = 0 # ๊ฑธ๋ฆฐ ์ดˆ
    baby = 2 # ์•„๊ธฐ ์ƒ์–ด์˜ ํฌ๊ธฐ
    eat = 0 # ํ˜„์žฌ ํฌ๊ธฐ์—์„œ ์ง€๊ธˆ๊นŒ์ง€ ๋จน์€ ๋จน์ด์˜ ์ˆ˜
    eat_flag = False  # ํ˜„์žฌ ์ƒํƒœ์—์„œ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์€ ๊ฒฝ์šฐ, for _ in range(size)๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•œ ํ”Œ๋ž˜๊ทธ

    answer = 0

    while q:
        size = len(q)

        q = deque(sorted(q))
        for _ in range(size):
            x, y = q.popleft()

            # ํ˜„์žฌ ์œ„์น˜์— ์•„๊ธฐ ์ƒ์–ด๋ณด๋‹ค ์ž‘์€ ๋ฌผ๊ณ ๊ธฐ๊ฐ€ ์žˆ์–ด, ์ด๋ฅผ ๋จน์€ ๊ฒฝ์šฐ
            if space[x][y] != 0 and space[x][y] < baby:
                space[x][y] = 0
                eat += 1

                if eat == baby:
                    baby += 1
                    eat = 0

                q, visited = deque(), set([(x,y)])
                eat_flag = True

                answer = seconds

            for _dx, _dy in zip(dx, dy):
                nx, ny = x + _dx, y + _dy
                if 0 <= nx < n and 0 <= ny < n and (nx, ny) not in visited:
                    if space[nx][ny] <= baby:
                        q.append((nx,ny))
                        visited.add((nx,ny))

            if eat_flag:
                eat_flag = False
                break

        seconds += 1
    return answer

n = int(sys.stdin.readline().strip())
space = [list(map(int,sys.stdin.readline().split())) for _ in range(n)]

# ์ดˆ๊ธฐ ์ƒ์–ด์˜ ์œ„์น˜๋ฅผ ํŒŒ์•…ํ•˜๊ณ , ํ•ด๋‹น ์ž๋ฆฌ๋ฅผ ํŒ์—์„œ ๋น„์šด๋‹ค.
x,y = None, None
for i in range(n):
    for j in range(n):
        if space[i][j] == 9:
            x,y = i,j
            space[i][j] = 0
            i = n + 1
            break

# ์‹œ์ž‘์ ์—์„œ bfs๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.
print(bfs(x,y))

์˜ค๋‹ต ์ฝ”๋“œ

import sys
sys.stdin = open("input.txt","rt")
sys.setrecursionlimit(10 ** 5)

# def calcDist(point1, point2):
#     x1, y1 = point1[0], point1[1]
#     x2, y2 = point2[0], point2[1]
#     return (x1-x2)**2 + (y1-y2)**2

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

res = float('inf')
def calcDist(start, end):
    # start์—์„œ end๋กœ ์•„๊ธฐ์ƒ์–ด๋ฅผ ์˜ฎ๊ธฐ๋Š”๋ฐ ๋“œ๋Š” ์ตœ๋‹จ๊ฑฐ๋ฆฌ
    global cnt, res
    if start == end:
        res = cnt if cnt < res else res
        return cnt
    else:
        x, y = start
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n and space[nx][ny] <= size_baby and visit[nx][ny] == 0:
                visit[nx][ny] = 1
                cnt += 1
                calcDist([nx,ny], end)
                visit[nx][ny] = 0
                cnt -= 1
    return res



n = int(sys.stdin.readline().strip())
space = list()
size_baby = 2 # ์•„๊ธฐ์ƒ์–ด์˜ ๊ธธ์ด
loc_baby = []
food = list() #์ฒ˜์Œ์— ํฌ๊ธฐ๊ฐ€ 1์ธ ๋จน์ด๋ฅผ ์ €์žฅ
seconds = 0
min_food = 1

def isFoodAvaliable(li, size):
    for i in range(n):
        for j in range(n):
            if 0 < li[i][j] <= size:
                food.append([i,j])

keyNum = 0
for i in range(n):
    temp = list(map(int,sys.stdin.readline().split()))
    for j in range(n):
        if temp[j] == 1:
            food.append([i,j]) #[์ขŒํ‘œ]
            keyNum += 1
        if temp[j] == 9: #์•„๊ธฐ ์ƒ์–ด์˜ ์œ„์น˜
            loc_baby = [i,j]
    space.append(temp)


eat = 0
while True:
    if len(food) == 0:
        break

    dist = list()
    for i in range(len(food)):
        cnt = 0
        visit = [[0] * n for _ in range(n)]
        visit[loc_baby[0]][loc_baby[1]] = 1
        res = float('inf')
        dist.append([i, calcDist(loc_baby,food[i])]) #[food์—์„œ์˜ ์ธ๋ฑ์Šค, ๊ฑฐ๋ฆฌ]

    dist.sort(key=lambda x:x[1])

    # ์ด๋™
    idx,d = dist.pop(0)
    seconds += d
    x, y = loc_baby
    space[x][y] = 0
    loc_baby = food[idx] #์•„๊ธฐ์ƒ์–ด์˜ ์œ„์น˜๋ฅผ ์˜ฎ๊ฒจ์คŒ
    x, y = loc_baby
    space[x][y] = 0
    food.pop(idx) #๋จน์ž‡๊ฐ์—์„œ ๋จน์€ ๊ฒƒ์„ ์—†์• ์คŒ
    eat += 1 #๋จน์—ˆ๋‹ค 1 ์ฆ๊ฐ€

    if eat == size_baby: #์ž์‹ ์˜ ํฌ๊ธฐ์™€ ๊ฐ™์€ ์ˆ˜์˜ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์—ˆ๋‹ค๋ฉด
        size_baby += 1 #์•„๊ธฐ์ƒ์–ด ํฌ๊ธฐ 1 ์ฆ๊ฐ€
        min_food += 1 #๋จน์„ ์ˆ˜ ์žˆ๋Š” ๋จน์ด ํฌ๊ธฐ 1 ์ฆ๊ฐ€
        eat = 0

    food = list() # food ์ดˆ๊ธฐํ™”, ์™œ๋ƒ๋ฉด ๊ฑฐ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์–ด์•ผํ•จ.....
    isFoodAvaliable(space, min_food)

print(seconds)