[BOJ] Q14391 종이조각
[BOJ] Q14391 종이조각
Question
Language: Python
Difficulty: Gold 3
해당 문제는 가능한 모든 직사각형의 모양을 고려하여 모든 경우에 대해 배치를 수행하여 얻을 수 있는 수의 최대값을 구하는 문제이다. 모든 좌표를 고려해야하기 때문에 dfs을 활용하면 된다. 이때, row * n_cols + col 값을 index로 잡아서 index 가 n_rows * n_cols가 될때 까지 dfs을 진행하면 된다.
Solution
#직사각형을 이루는 좌표들이 모두 이전에 방문하지 않았는지 확인
def check_visited(row,col,max_dy,max_dx):
for dy in range(max_dy+1):
for dx in range(max_dx+1):
if visited[row+dy][col+dx]:
return True
return False
def solution(index,total_point):
global max_point,visited
#모든 점을 다 탐색한 경우
if index == (n_rows * n_cols):
max_point=max(max_point,total_point)
return
row=index // n_cols
col=index % n_cols
#이미 방문한 좌표인 경우
if visited[row][col]:
solution(index+1,total_point)
#가능한 직사각형의 경우를 모두 대입해본다.
for max_dy,max_dx in rectangle_types:
next_row=row+max_dy
next_col=col+max_dx
#격자 범위를 벗어나는 경우
if next_row >= n_rows or next_col >= n_cols:
continue
#이미 처리된 경우
if check_visited(row,col,max_dy,max_dx):
continue
rectangle_point=""
#해당 직사각형을 이루는 점을 모두 방문 처리하고, 직사각형을 이루는 수를 구한다.
for dy in range(max_dy+1):
for dx in range(max_dx+1):
visited[row+dy][col+dx]=True
rectangle_point+=str(board[row+dy][col+dx])
rectangle_point=int(rectangle_point)
solution(index+1,total_point+rectangle_point)
#해당 직사각형을 이루는 점을 모두 방문해제 처리한다.
for dy in range(max_dy+1):
for dx in range(max_dx+1):
visited[row+dy][col+dx]=False
if __name__ == "__main__":
n_rows,n_cols=map(int,input().split())
board=[list(map(int,list(input()))) for _ in range(n_rows)]
max_point=0
rectangle_types=[(0,0)]
#세로 모양
for i in range(1,n_rows):
rectangle_types.append((i,0))
#가로 모양
for i in range(1,n_cols):
rectangle_types.append((0,i))
visited=[[False] * n_cols for _ in range(n_rows)]
solution(0,0)
print(max_point)
댓글남기기