문제
https://www.acmicpc.net/problem/14502
생각한 과정
- 1을 딱 세 개만 추가해서 2가 최대한 안 퍼지도록 해야한다 !
- 0인 칸들의 좌표를 넣어 두고
- 그 안에서 조합을 이용해 세 개를 꺼내 벽을 세우고
- 벽을 세운 경우들마다 bfs를 통해 바이러스를 퍼뜨리고 안전영역의 크기를 최댓값으로 업데이트
코드
import sys
from collections import deque
from itertools import combinations
input = sys.stdin.readline
n, m = map(int, input().rstrip().split())
graph = [list(map(int, input().rstrip().split())) for _ in range(n)]
# 상좌하우
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
candidate = []
result = 0
virus_zone = []
# 2주변에 0인 칸들의 좌표를 저장하는 함수
def find_candidate():
for x in range(n):
for y in range(m):
# 만약 좌표값이 2이면
if graph[x][y] == 2:
virus_zone.append((x, y))
# 방향 돌면서 인덱스 내부 범위의 좌표값에 대해 0인지 점검하고 0이면 후보에 좌표 넣기
if graph[x][y] == 0:
candidate.append((x, y))
def find_safezone():
global result
temp_graph = [item[:] for item in graph]
queue = deque(virus_zone)
while queue:
# x,y는 바이러스의 시작 지점이다
x, y = queue.popleft()
for i in range(4):
nx = x+dx[i]
ny = y+dy[i]
# 인덱스 범위 내에서 바이러스 주변 좌표값이 0이면 바이러스로 채움
if 0 <= nx < n and 0 <= ny < m:
if temp_graph[nx][ny] == 0:
temp_graph[nx][ny] = 2
# 바이러스로 채운 곳은 새로운 전파지점이 되므로 큐에 추가
queue.append((nx, ny))
# 이거 초기화 해주는 과정 필요
# 반복문을 나온 이후 그래프에서 0의 값을 셈
temp = 0
for i in range(n):
for j in range(m):
if temp_graph[i][j] == 0:
temp += 1
result = max(result, temp)
# 1이 들어갈 수 있는 좌표들을 찾음
can_find = find_candidate()
# 가능한 조합들을 돌면서 result 업데이트 할 것
for set in combinations(candidate, 3):
# 여기 들어왔을 때 한 세트의 벽(총 3개의 벽)이 세워짐
graph[set[0][0]][set[0][1]] = 1
graph[set[1][0]][set[1][1]] = 1
graph[set[2][0]][set[2][1]] = 1
# 큐에서 2의 좌표 꺼내서 주변 탐색하면서 만약 0이면 다 2로 채워버린 후 안전영역 크기 최대값으로 계속 갱신
find_safezone()
# 함수로 안전역역 크기 값 갱신했으면 그래프 값 갱신
graph[set[0][0]][set[0][1]] = 0
graph[set[1][0]][set[1][1]] = 0
graph[set[2][0]][set[2][1]] = 0
print(result)
알게된 것
- 깊은 복사는 슬라이싱을 이용하는 것이 빠르다
temp_graph = [item[:] for item in graph]
- 원형 리스트를 유지하기 위해 원본 리스트를 바뀌고 다시 초기화시키는 것보다, 함수를 호출할 때 변수에 원형 리스트를 담아 변수를 변형시키는 것이 더 시간 효율적이다
'Algorithm' 카테고리의 다른 글
DP JS로 구현하기 (0) | 2021.10.28 |
---|---|
BFS&DFS 알고리즘 JS로 구현하기 (0) | 2021.10.14 |
편집거리 알고리즘 (0) | 2021.09.26 |
Javascript 알고리즘 #2 소수 찾기 (0) | 2021.04.11 |
Javascript 알고리즘 #1 두 개 뽑아서 더하기 (0) | 2021.04.11 |