[파이썬] 백준 1888 : 곰팡이 (골드3)
1888번: 곰팡이
첫 줄에 곰팡이가 피어 있는 벽의 크기를 나타내는 두 정수 m과 n이 주어진다. (1 ≤ m, n ≤100) 둘째 줄부터는 벽의 상황이 한 줄에 한 행씩 주어진다. 곰팡이가 피어있는 곳은 그 곰팡이의 자라는
www.acmicpc.net
문제
풀이
0. 방향성 생각
- 곰팡이가 사방으로 퍼져나간다.
- 한 덩어리로 된 것을 판별하려면 각 군집별로 disjoint set을 사용하거나 BFS를 돌려서 개수를 카운트 해주는 방법이 있다.
- 본인은 후자로 풀이. 곰팡이 군집을 만날때마다 카운팅을 해줘서 1개가 되는 순간의 날짜를 출력
1. 입력
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(map(int,input())) for _ in range(h)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
inside = lambda x,y : 0<=x<w and 0<=y<h
- inside는 격자 내 들어오는지 확인하는 함수
2. 곰팡이 덩어리 개수 카운트
def bfs(x,y,n): # 곰팡이 덩어리 BFS
visit[y][x] = True
q = deque([(x,y)])
while q:
x,y = q.popleft()
for dx,dy in dire:
nx,ny = x+dx,y+dy
if inside(nx,ny) and not visit[ny][nx] and arr[ny][nx]:
visit[ny][nx] = True
q.append((nx,ny))
def check(): # 곰팡이 덩어리 개수 세는 함수
cnt = 0
for i in range(h):
for j in range(w):
if arr[i][j] and not visit[i][j]:
bfs(j,i,arr[i][j])
cnt += 1
return cnt
- BFS를 돌려서 곰팡이를 만나면 계속 큐에 추가
- check는 BFS를 돌리면서 덩어리가 몇개인지 카운트
3. 곰팡이 퍼짐 구현
def spread():
narr = [[0]*w for _ in range(h)]
for y in range(h):
for x in range(w):
speed = arr[y][x]
narr[y][x] = max(narr[y][x],arr[y][x])
if speed:
for nx in range(x-speed,x+speed+1):
for ny in range(y-speed,y+speed+1):
if inside(nx,ny) and arr[ny][nx] < arr[y][x]:
narr[ny][nx] = max(narr[ny][nx],arr[y][x])
return narr
- 특정 좌표 x,y를 기준으로 그 곰팡이의 속도 += speed 범위 내의 격자를 조사한다.
- 속도가 빠른 곰팡이가 퍼져서 속도가 느린 곰팡이에 영향을 주면 안된다.
- 속도가 느린 곰팡이도 동시에 퍼지므로 구현해야한다는 말
- 새로운 narr이라는 어레이를 만들고 업데이트는 narr쪽에 해준다.
4. 시뮬레이션
day = 0
visit = [[False]*w for _ in range(h)]
count = check()
while count > 1:
visit = [[False]*w for _ in range(h)]
arr = spread()
count = check()
day += 1
print(day)
- 시뮬레이션
- visit은 계속 초기화시켜줘야한다.
전체코드
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(map(int,input())) for _ in range(h)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
inside = lambda x,y : 0<=x<w and 0<=y<h
def bfs(x,y,n): # 곰팡이 덩어리 BFS
visit[y][x] = True
q = deque([(x,y)])
while q:
x,y = q.popleft()
for dx,dy in dire:
nx,ny = x+dx,y+dy
if inside(nx,ny) and not visit[ny][nx] and arr[ny][nx]:
visit[ny][nx] = True
q.append((nx,ny))
def check(): # 곰팡이 덩어리 개수 세는 함수
cnt = 0
for i in range(h):
for j in range(w):
if arr[i][j] and not visit[i][j]:
bfs(j,i,arr[i][j])
cnt += 1
return cnt
def spread():
narr = [[0]*w for _ in range(h)]
for y in range(h):
for x in range(w):
speed = arr[y][x]
narr[y][x] = max(narr[y][x],arr[y][x])
if speed:
for nx in range(x-speed,x+speed+1):
for ny in range(y-speed,y+speed+1):
if inside(nx,ny) and arr[ny][nx] < arr[y][x]:
narr[ny][nx] = max(narr[ny][nx],arr[y][x])
return narr
day = 0
visit = [[False]*w for _ in range(h)]
count = check()
while count > 1:
visit = [[False]*w for _ in range(h)]
arr = spread()
count = check()
day += 1
print(day)
코멘트
.
'Algorithm > Simulation' 카테고리의 다른 글
[파이썬] 코드트리 : 타워 부수기 (골드1) (0) | 2024.02.29 |
---|---|
[파이썬] 코드트리 싸움땅 (골드2) (0) | 2024.02.25 |
[파이썬] 코드트리 메이즈러너 (골드3) (0) | 2024.02.18 |
[파이썬] 백준 17143 : 낚시왕 (골드1) (0) | 2023.12.26 |
[파이썬] 백준 9328 : 열쇠 (골드1) (0) | 2023.12.19 |
[파이썬] 백준 20055 : 컨베이어 벨트 위의 로봇 (골드5) (0) | 2023.10.10 |
[파이썬] 백준 18405: 경쟁적 전염 (골드5) (0) | 2023.09.20 |
댓글