[파이썬] 백준 17141 : 연구소2 (골드4)
17141번: 연구소 2
인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이러
www.acmicpc.net
문제
풀이
0. 방향성 생각
완탐 + BFS
1. 입력
from itertools import combinations as C
from collections import deque
import sys
input = sys.stdin.readline
N,M = map(int,input().split())
arr = [list(map(int,input().split())) for i in range(N)]
virus = set()
for i in range(N):
for j in range(N):
if arr[i][j] == 2:
virus.add((j,i))
virus에 바이러스 위치 넣기
2. BFS 함수 정의
activation = list(C(virus,M))
step = [[1,-1,0,0],[0,0,1,-1]]
def bfs(array,act_virus):
visit = [[-1]*N for _ in range(N)]
q = deque()
for a,b in act_virus:
q.append((a,b))
visit[b][a] = 0
while q:
x,y = q.popleft()
for i in range(4):
nx = x + step[0][i]
ny = y + step[1][i]
if 0<=nx<N and 0<=ny<N :
if array[ny][nx] != 1 and visit[ny][nx] == -1:
visit[ny][nx] = visit[y][x] + 1
q.append((nx,ny))
time = 0
for i in range(N):
for j in range(N):
if visit[i][j] == -1 and array[i][j] == 0 :
return -1
if time < visit[i][j] :
time = visit[i][j]
return time
virus 중 바이러스 M개를 뽑는다.
반복작업 해야해서 함수 지역변수에서 돌리는게 빠름
array에 바이러스를 놓고 바이러스를 놓지 않는 곳에는 빈공간으로 수정해준 지도 array을 넣는다.
큐에 virus 위치 넣으주고 BSF 돌리기.
3. 출력
answer = []
for act in activation:
temp = [row[:] for row in arr]
for x,y in virus:
if (x,y) not in act:
temp[y][x] = 0
answer.append(bfs(temp,act))
if set(answer) == set([-1]) : print(-1)
else : print(min([i for i in answer if i != -1]))
계속 arr의 copy본을 사용해야함. deep copy 사용해도 상관 없는데 [:]형태로 써주면 새로운 객체 생성 가능.
활성바이러스를 놓지 않는 곳은 0으로 수정.
answer의 원소가 -1 뿐이면 전부 실패 -> -1 출력
그렇지 않은 경우는 -1 제외 가장 작은값
전체코드
from itertools import combinations as C
from collections import deque
import sys
input = sys.stdin.readline
N,M = map(int,input().split())
arr = [list(map(int,input().split())) for i in range(N)]
virus = set()
for i in range(N):
for j in range(N):
if arr[i][j] == 2:
virus.add((j,i))
activation = list(C(virus,min(M,len(virus))))
step = [[1,-1,0,0],[0,0,1,-1]]
def bfs(array,act_virus):
visit = [[-1]*N for _ in range(N)]
q = deque()
for a,b in act_virus:
q.append((a,b))
visit[b][a] = 0
while q:
x,y = q.popleft()
for i in range(4):
nx = x + step[0][i]
ny = y + step[1][i]
if 0<=nx<N and 0<=ny<N :
if array[ny][nx] != 1 and visit[ny][nx] == -1:
visit[ny][nx] = visit[y][x] + 1
q.append((nx,ny))
time = 0
for i in range(N):
for j in range(N):
if visit[i][j] == -1 and array[i][j] == 0 :
return -1
if time < visit[i][j] :
time = visit[i][j]
return time
answer = []
for act in activation:
temp = [row[:] for row in arr]
for x,y in virus:
if (x,y) not in act:
temp[y][x] = 0
answer.append(bfs(temp,act))
if set(answer) == set([-1]) : print(-1)
else : print(min([i for i in answer if i != -1]))
코멘트
연구소 2풀다가 3으로 넘어가서 풀다가 삽질함.
바이러스 안놓으면 빈칸인거 까먹어서 삽질함
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 프로그래머스 : 단어 변환 (Lv.2) (0) | 2023.07.20 |
---|---|
[파이썬] 백준 3184, 3187 : 양, 양치기 꿍 (실버1) (0) | 2023.07.13 |
[파이썬] 백준 연구소3 : 17142 (골드3) (0) | 2023.07.12 |
[파이썬] 백준 14502 : 연구소 (골드4) (0) | 2023.07.11 |
[파이썬] 프로그래머스 : 미로탈출 (Lv.2) (0) | 2023.07.07 |
[파이썬] 프로그래머스 : 광물캐기 (Lv.2) (0) | 2023.07.07 |
[파이썬] 백준 5567 : 결혼식 (실버2) (0) | 2023.07.06 |
댓글