Algorithm(CodeTree, Python)/BFS

[코드트리] 우리는 하나 Python

kurooru 2023. 2. 28. 23:52
# n, k, u, d 입력
n, k, u, d = map(int, input().split())
# maps
maps = [
    list(map(int, input().split()))
    for _ in range(n)
]

# in_range
def in_range(x, y):
    return 0 <= x < n and 0 <= y < n

# is_connected
def is_connected(x, y, curr_num):
    # 범위 내에 있고, 방문한 적 없으며, 차이가 u 이상 d 이하면 됨
    return in_range(x, y) and not visited[x][y] and u <= abs(curr_num - maps[x][y]) <= d

# bfs
def bfs():
    global visited

    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 is_connected(nx, ny, maps[x][y]):
                q.append((nx, ny))
                visited[nx][ny] = True

# get_cnt
def get_cnt(curr_state):
    global visited

    # curr_cnt
    curr_cnt = 0

    # visited
    visited = [
        [False] * n
        for _ in range(n)
    ]

    for state in curr_state:
        x, y = state
        q.append((x, y))
        visited[x][y] = True
        bfs()
    
    # visited를 돌면서
    for i in range(n):
        for j in range(n):
            # 방문 흔적을 찾으면
            if visited[i][j]:
                # curr_cnt에 추가
                curr_cnt += 1
    
    # 반환
    return curr_cnt

# simulate
def simulate(curr_idx, cnt):
    # 전역 변수 선언
    global max_cnt
    # 종료조건
    if cnt == k:
        # max_cnt update
        max_cnt = max(max_cnt, get_cnt(selected_state))
        return
    if curr_idx == n**2:
        return
    selected_state.append(state_pos[curr_idx])
    simulate(curr_idx + 1, cnt + 1)
    selected_state.pop()
    simulate(curr_idx + 1, cnt)

# 설계
# state_pos
state_pos = []
for i in range(n):
    for j in range(n):
        state_pos.append((i, j))

# 큐 사용준비
from collections import deque
q = deque()

# max_cnt
max_cnt = 0

# selected_state
selected_state = []
# simulate
simulate(0, 0)

# 출력
print(max_cnt)