코딩테스트/SWEA
[Python, 파이썬] SWEA 1861. 정사각형 방
알코딩
2024. 10. 16. 00:22
어떤 수가 적힌 방에서 있어야 가장 많은 개수의 방을 이동할 수 있는지 구하는 프로그램
당신이 어떤 방에 있다면, 상하좌우에 있는 다른 방으로 이동할 수 있다.
물론 이동하려는 방이 존재해야 하고, 이동하려는 방에 적힌 숫자가 현재 방에 적힌 숫자보다 정확히 1 더 커야 한다.
이동할 수 있는 방의 수가 가장 많은 방의 번호는?
def Get():
A = [[0 for i in range(N+2)]] # 수열 A
# 수열 입력받기
for i in range(N):
A.append([0]+list(map(int, input().split()))+[0])
A.append([0 for i in range(N+2)])
return A
def Graph(A):
next_room = [[] for i in range(N*N+1)]
for i in range(1, N+1):
for j in range(1, N+1):
v = A[i][j] # 현재 블록
next_ = next((num for num in [A[i][j-1], A[i][j+1], A[i-1][j], A[i+1][j]] if num == A[i][j] + 1), 0) # 갈 수 있는 블록
next_room[v]= next_ # 다음 room 저장
return next_room
def DFS(i, dep):
global max_depth
if(room[i]): # 탐색한 room이면 더 이상 탐색 x
max_depth = dep+room[i]-1 # 메모이제이션 사용해 최대값 구함
return
max_depth = max(max_depth, dep) # 최대 깊이 갱신
if(next_room[i]): # 다음 room이 있으면
DFS(next_room[i], dep+1) # 연결된 room 탐색
T = int(input()) # 테스트케이스 수 T
for test_case in range(1, T+1):
N = int(input()) # 정수 N
A = Get() # 수열 입력받기
next_room = Graph(A) # 경로 배열 생성
room = [0]*(N*N+1) # 최대 이동할 수 있는 방의 개수를 저장해 둔 배열
# 탐색 시작
for i in range(N*N, 0, -1):
max_depth = 1
DFS(i, 1) # 최대 방 개수 계산
room[i] = max_depth # 방 업뎃
# 가장 최대인 방 탐색
max_index = room.index(max(room))
print("#%d %d %d" %(test_case, max_index, room[max_index]))
[문제풀이]
와.... 이 문제 장난 아니였다.
D4를 처음 풀어보는 데 5-6시간은 걸렸다.
막상 풀고 나니 코드가 좀 간단한데 처음 푸는 거라 무척 헤맸다:(

우선 입력받은 배열 요소의 상하좌우를 검사하기 위해 이렇게 0으로 이루어진 한겹 패딩을 쳐줬다.

그 후 이렇게 배열 요소 하나하나 상하좌우를 검사해 갈 수 있는 다음번 room이 있는지 검사해줬다.
현재 room +1 번째 room으로만 갈 수 있기 때문에 있으면 다음번 room 번호, 없으면 0을 넣어줬다.
그 다음 DFS으로 최대 갈 수 있는 경로를 확인만 해주면 된다.
if(next_room[i]): # 다음 room이 있으면
DFS(next_room[i], dep+1) # 연결된 room 탐색
연결된 다음 room이 있을 시 이동하고, 연결된 방의 개수를 +1 해주면 된다.
그러나 경로를 일일이 다 확인하면 시간 초과가 난다. 그래서 메모이제이션을 이용해 시간 단축을 해줘야 한다.
if(room[i]): # 탐색한 room이면 더 이상 탐색 x
max_depth = max(dep+room[i], max_depth) # 최대값 갱신
return
최대 이동할 수 있는 방의 개수를 저장해 둔 room 배열을 확인해 이미 탐색한 방일 시 그 값을 이용해 시간 단축!
그럼 시간 내에 문제 없이 문제를 pass 할 수 있다.