πŸ”‘ CS/μ½”λ”©ν…ŒμŠ€νŠΈ

[λ°±μ€€ 7569번] ν† λ§ˆν†  (python/파이썬)

볡만 2022. 9. 9. 15:29

λΆ„λ…Έμ˜ ν† λ§ˆν† ...πŸ…

접근방법이 ν‹€λ €μ„œ μ•Œκ³ λ¦¬μ¦˜μ„ λͺ‡λ²ˆμ”© μˆ˜μ •ν–ˆλ‹€

 

🌼 문제 링크

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

 

7569번: ν† λ§ˆν† 

첫 μ€„μ—λŠ” μƒμžμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •μˆ˜ M,Nκ³Ό μŒ“μ•„μ˜¬λ €μ§€λŠ” μƒμžμ˜ 수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Hκ°€ 주어진닀. M은 μƒμžμ˜ κ°€λ‘œ 칸의 수, N은 μƒμžμ˜ μ„Έλ‘œ 칸의 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

  • ν‹°μ–΄: κ³¨λ“œ V
  • λΆ„λ₯˜: κ·Έλž˜ν”„ 이둠, κ·Έλž˜ν”„ 탐색, λ„ˆλΉ„ μš°μ„  탐색

 

 

❗ TRIAL 1.

더보기
μ½”λ“œ
import sys
input = sys.stdin.readline

from collections import deque

M, N, H = map(int, input().split())

#fill tomatos (-1: no tomato, 0: raw tomato, 1: grown tomato)
tmt = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)]
for h in range(H):
    for n in range(N):
        tmt[h][n] = list(map(int, input().split()))

#BFS
adjs = [(1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)]
def BFS(v):
    visited = [[[False for _ in range(M)] for _ in range(N)] for _ in range(H)]
    queue = deque([(v, 0)])
    visited[v[0]][v[1]][v[2]] = True
    while queue:
        v, cnt = queue.popleft()
        for d in adjs:
            new_v = [v[i]+d[i] for i in range(3)]
            if 0<=new_v[0]<H and 0<=new_v[1]<N and 0<=new_v[2]<M:
                if tmt[new_v[0]][new_v[1]][new_v[2]] == 1:
                    return cnt+1
                elif not visited[new_v[0]][new_v[1]][new_v[2]] and tmt[new_v[0]][new_v[1]][new_v[2]] == 0:
                    visited[new_v[0]][new_v[1]][new_v[2]] = True
                    queue.append([new_v, cnt+1])
    return -1

def solution():
    maxcount = 0
    for h in range(H):
        for n in range(N):
            for m in range(M):
                if tmt[h][n][m] == 0:
                    cnt = BFS([h, n, m])
                    if cnt == -1:
                        return -1
                    if cnt > maxcount:
                        maxcount = cnt
    return maxcount

print(solution())

 

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

 

- 읡은 ν† λ§ˆν† μ—μ„œ ν•œ μŠ€ν…μ”© μ΅ν˜€κ°€λŠ”κ²Œ μ•„λ‹ˆλΌ,

- λͺ¨λ“  μ•ˆμ΅μ€ ν† λ§ˆν† μ— λŒ€ν•΄ 읡은 ν† λ§ˆν† κΉŒμ§€μ˜ μ΅œλ‹¨κ±°λ¦¬λ₯Ό κ΅¬ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν’ˆ

 

ν‹€λ¦° 원인

 

μ‹œκ°„μ΄ˆκ³Όκ·Έλƒ₯ λ¬Έμ œμ—μ„œ 주어진 λŒ€λ‘œ 읡은 ν† λ§ˆν† μ—μ„œ ν•œ μŠ€ν…μ”© λ‚˜μ•„κ°€λŠ” 게 더 λΉ λ₯΄λ‹€.

 

 

❗ TRIAL 2.

더보기
μ½”λ“œ
import sys
input = sys.stdin.readline

from collections import deque

M, N, H = map(int, input().split())

#fill tomatos (-1: no tomato, 0: raw tomato, 1: grown tomato)
tmt = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)]
for h in range(H):
    for n in range(N):
        tmt[h][n] = list(map(int, input().split()))

#list of grown tomatos
growns = []
num_target = 0
for h in range(H):
    for n in range(N):
        for m in range(M):
            if tmt[h][n][m] == 1:
                growns.append((h, n, m))
            elif tmt[h][n][m] == 0:
                num_target += 1

dhs = [1, -1, 0, 0, 0, 0]
dns = [0, 0, 1, -1, 0, 0]
dms = [0, 0, 0, 0, 1, -1]

cnt = 0
while num_target > 0:
    new_target = num_target
    growns_tmp = []
    for vh, vn, vm in growns:
        for dh, dn, dm in zip(dhs, dns, dms):
            newh, newn, newm = vh+dh, vn+dn, vm+dm
            if 0<=newh<H and 0<=newn<N and 0<=newm<M:
                if tmt[newh][newn][newm] == 0:
                    tmt[newh][newn][newm] = 1
                    new_target -= 1
                    growns_tmp.append((newh, newn, newm))
    if new_target == num_target:
        cnt = -1
        break
    growns.extend(growns_tmp)
    num_target = new_target
    cnt += 1

print(cnt)

 

μˆ˜μ •ν•œ λΆ€λΆ„

 

- 읡은 ν† λ§ˆν† μ˜ λͺ©λ‘μ„ μ²˜μŒμ— μ €μž₯ν•˜κ³ ,

- 맀 stepλ§ˆλ‹€ μΈμ ‘ν•œ 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ„ μ΅νžŒλ‹€.

- μ²˜μŒμ— 읡지 μ•Šμ€ ν† λ§ˆν† μ˜ 갯수λ₯Ό countν•˜κ³ ,

- 맀 step이 끝날 λ•Œ 읡지 μ•Šμ€ ν† λ§ˆν† μ˜ κ°―μˆ˜κ°€ 쀄지 μ•Šμ•˜μœΌλ©΄ 진행을 λ©ˆμΆ”κ³  -1을 λ°˜ν™˜, (더이상 진행할 수 μ—†μŒ)

- 읡지 μ•Šμ€ ν† λ§ˆν† κ°€ μ—†μœΌλ©΄ 총 step 수λ₯Ό returnν•œλ‹€.

 

ν‹€λ¦° 원인

 

μ‹œκ°„μ΄ˆκ³Ό. 맀 stepλ§ˆλ‹€, ν•œλ²ˆ κ²€μ‚¬ν•œ 읡은 ν† λ§ˆν† λŠ” λ‹€μŒλ²ˆμ— κ²€μ‚¬ν•˜μ§€ μ•Šμ•„λ„ 됨 (이미 인접 ν† λ§ˆν† λŠ” λ‹€ μ΅μ—ˆμœΌλ‹ˆκΉŒ)

 

πŸ’‘ Solution

μ½”λ“œ
import sys
input = sys.stdin.readline

from collections import deque

M, N, H = map(int, input().split())

#fill tomatos (-1: no tomato, 0: raw tomato, 1: grown tomato)
tmt = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)]
for h in range(H):
    for n in range(N):
        tmt[h][n] = list(map(int, input().split()))

growns = deque([])
num_target = 0
for h in range(H):
    for n in range(N):
        for m in range(M):
            if tmt[h][n][m] == 1:
                growns.append((h, n, m))
            elif tmt[h][n][m] == 0:
                num_target += 1

dhs = [1, -1, 0, 0, 0, 0]
dns = [0, 0, 1, -1, 0, 0]
dms = [0, 0, 0, 0, 1, -1]

cnt = 0
while num_target > 0:
    new_target = num_target
    new_growns = deque([])
    while growns:
        vh, vn, vm = growns.popleft()
        for dh, dn, dm in zip(dhs, dns, dms):
            newh, newn, newm = vh+dh, vn+dn, vm+dm
            if 0<=newh<H and 0<=newn<N and 0<=newm<M:
                if tmt[newh][newn][newm] == 0:
                    tmt[newh][newn][newm] = 1
                    new_target -= 1
                    new_growns.append((newh, newn, newm))
    if new_target == num_target:
        cnt = -1
        break
    num_target = new_target
    growns = new_growns
    cnt += 1

print(cnt)

 

μ½”λ“œ μ„€λͺ…
  • 읡은 ν† λ§ˆν† μ˜ λͺ©λ‘μ„ μ²˜μŒμ— μ €μž₯ν•˜κ³  (growns),
  • 맀 stepλ§ˆλ‹€ 읡은 ν† λ§ˆν† μ™€ μΈμ ‘ν•œ 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ„ μ΅νžŒλ‹€. 이 λ•Œ μƒˆλ‘­κ²Œ 읡은 ν† λ§ˆν† λ“€μ˜ λͺ©λ‘μ„ μ €μž₯ν•œλ‹€ (new_gronws).
  • μ²˜μŒμ— 읡지 μ•Šμ€ ν† λ§ˆν† μ˜ 갯수λ₯Ό countν•˜κ³  (num_target),
  • 맀 step이 끝날 λ•Œ 읡지 μ•Šμ€ ν† λ§ˆν† μ˜ κ°―μˆ˜κ°€ 쀄지 μ•Šμ•˜μœΌλ©΄ (if new_target == num_target) 진행을 λ©ˆμΆ”κ³  -1을 λ°˜ν™˜, (더이상 진행할 수 μ—†μŒ)
  • 읡지 μ•Šμ€ ν† λ§ˆν† κ°€ μ—†μœΌλ©΄ 총 step 수λ₯Ό returnν•œλ‹€.
  • λ‹€μŒ stepμ—μ„œλŠ” μƒˆλ‘­κ²Œ 읡은 ν† λ§ˆν† λ“€μ˜ λͺ©λ‘μ„ μ΄μš©ν•΄ λ™μΌν•˜κ²Œ μ§„ν–‰ν•œλ‹€.
  •  
λ°˜μ‘ν˜•