Algorithm(CodeTree, Python)/BFS
[코드트리] 돌 잘 치우기 Python
kurooru
2023. 2. 28. 19:53
# n, k, m 입력
n, k, m = map(int, input().split())
# grid 입력
grid = [
list(map(int, input().split()))
for _ in range(n)
]
# start_points
start_points = [
tuple(map(int, input().split()))
for _ in range(k)
]
# in_range(x, y)
def in_range(x, y):
return 0 <= x < n and 0 <= y < n
# can_go(x, y)
def can_go(x, y):
# 범위 내에 있고, 방문한 적 없고, 돌이 없으면 가능
return in_range(x, y) and not visited[x][y] and not temp_grid[x][y]
# bfs()
def bfs():
while q:
x, y = q.popleft()
dxs, dys = [-1, 1, 0, 0], [0, 0, -1, 1]
for dx, dy in zip(dxs, dys):
nx, ny = x + dx, y + dy
# 갈 수 있으면
if can_go(nx, ny):
q.append((nx, ny))
visited[nx][ny] = True
# get_cnt(curr_del_stones)
def get_cnt(curr_del_stones):
global visited, temp_grid
# temp_grid
temp_grid = [
[0] * n
for _ in range(n)
]
for i in range(n):
for j in range(n):
temp_grid[i][j] = grid[i][j]
# 제거할 돌 제거
for del_pos in curr_del_stones:
# unpacking
x, y = del_pos
# 바꿔주기
temp_grid[x][y] = 0
# 시작점들을 돌면서
for point in start_points:
# unpacking
x, y = point
x -= 1
y -= 1
# bfs
q.append((x, y))
visited[x][y] = True
bfs()
# curr_cnt
curr_cnt = 0
# visited를 돌면서
for i in range(n):
for j in range(n):
# 방문한 점을 만나면
if visited[i][j]:
# curr_cnt에 추가
curr_cnt += 1
# visited 초기화
visited = [
[ False ] * n
for _ in range(n)
]
# 반환
return curr_cnt
# simulate(curr_idx, cnt)
def simulate(curr_idx, cnt):
# 전역 변수 선언
global max_cnt
# 종료 조건
if curr_idx == stone_num:
if cnt == m:
# max_cnt update
max_cnt = max(max_cnt, get_cnt(delete_stones))
return
delete_stones.append(stone_points[curr_idx])
simulate(curr_idx + 1, cnt + 1)
delete_stones.pop()
simulate(curr_idx + 1, cnt)
# 설계
# stone_points
stone_points = []
for i in range(n):
for j in range(n):
# 돌을 발견하면
if grid[i][j]:
# stone_points에 추가
stone_points.append((i, j))
# stone_num
stone_num = len(stone_points)
# max_cnt
max_cnt = 0
# delete_stones
delete_stones = []
# 큐 사용준비
from collections import deque
q = deque()
# visited
visited = [
[ False ] * n
for _ in range(n)
]
# m개의 돌 고르고 제거하여 최대 도달 가능 칸 update하기
simulate(0, 0)
# 출력
print(max_cnt)