grid)로 격자형 지도를 표현하고, 방문 여부를 기록할 동일한 크기의 2차원 불리언 리스트(visited)를 사용한다.max_v)를 찾는다.max_v와 같은 높이를 가진 모든 좌표를 starting 리스트에 담아둔다.DFS 함수 수행 시 실시간으로 변하는 상태 정보를 매개변수(인자)로 들고 다닌다.
(y, x): 현재 내가 발을 디디고 서 있는 좌표length: 현재까지 연결된 등산로의 총 길이bool_shit: 지형을 한 번이라도 깎았는지 여부 (이미 깎았다면 True, 아직 찬스가 있다면 False)주변 4방향을 탐색할 때 다음 두 가지 케이스로 분기 처리했다.
grid[sy][sx] > grid[ny][nx])bool_shit)를 그대로 토스하며 dfs를 이어간다. 재귀가 끝나면 방문을 해제한다.grid[sy][sx] <= grid[ny][nx])not bool_shit), 현재 내 높이보다 딱 1만큼만 낮아지도록 최소한으로 깎는 깊이(min_cut = grid[ny][nx] - grid[sy][sx] + 1)를 계산한다.min_cut이 최대 허용치인 K 이하인 경우에만 cut_that_shit을 호출하여 산을 깎고, 찬스 상태를 True로 변경하여 dfs를 재귀 호출한다.-min_cut)와 방문 배열을 반드시 원래대로 되돌려 놓는 백트래킹 처리가 필수적이다.def find_starting():
max_v = -1
for y in range(N):
for x in range(N):
if max_v < grid[y][x]:
max_v = grid[y][x]
for y in range(N):
for x in range(N):
if grid[y][x] == max_v:
starting.append((y, x))
def cut_that_shit(y, x, k):
grid[y][x] -= k
def dfs(y, x, length, bool_shit):
global ans
if ans < length:
ans = length
sy, sx = y, x
for i in range(4):
ny, nx = sy + dy[i], sx + dx[i]
if 0 <= ny < N and 0 <= nx < N and not visited[ny][nx]:
# 다음 가려는 후보지가 현재 위치보다 낮은 경우
if grid[sy][sx] > grid[ny][nx]:
visited[ny][nx] = True
dfs(ny, nx, length + 1, bool_shit)
visited[ny][nx] = False
# 다음 후보지가 현재 위치보다 같거나 높다면?
elif grid[sy][sx] <= grid[ny][nx]:
if not bool_shit:
min_cut = grid[ny][nx] - grid[sy][sx] + 1
if min_cut <= K:
cut_that_shit(ny, nx, min_cut)
visited[ny][nx] = True
dfs(ny, nx, length + 1, True)
cut_that_shit(ny, nx, -min_cut)
visited[ny][nx] = False
# 상 우 하 좌
dx = [0, 1 ,0, -1]
dy = [-1, 0, 1, 0]
T = int(input())
for tc in range(1, T+1):
N, K = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(N)]
visited = [[False] * N for _ in range(N)]
starting = []
find_starting()
ans = 1
for sy, sx in starting:
visited[sy][sx] = True
dfs(sy, sx, 1, False)
visited[sy][sx] = False
print(f"#{tc} {ans}")