Algorithm/백준_생각정리
백준_18430_무기공학(python)
코친남
2023. 3. 4. 21:45
※ 접근법
n의 범위가 크지 않았기 때문에 모든 경우의 수를 백트래킹을 활용하여 큰 수를 구해야겠다고 생각했다. 4가지 모양을 가지고 각 좌표에 대해서 해당 모양이 될 수 있는지 없는지를 범위와, 방문 여부로 판단했다.
※ 풀이
1. 0,0부터 visited,0을 가지고 dfs(solve함수)를 시작한다.
2. y좌표를 1씩 이동했고 y좌표가 배열의 범위를 벗어났다면 x += 1, y= 0을 해줬다.
3. 최댓값을 어느 시점에서 걸어서 백트래킹을 걸까(return을 할까) 했었는데 x가 배열의 범위를 벗어났을때는 이미 탐색을 다 한 것이니 x == n일때 해주면 됐다.
n,m = map(int,input().split())
data = [list(map(int,input().split())) for _ in range(n)]
max_num = 0
def high_left(r,c,visited):
if c + 1 == m or r + 1 == n:
return False
if visited[r][c] == 1 or visited[r][c+1] == 1 or visited[r+1][c] == 1:
return False
visited[r][c] = 1
visited[r][c+1] = 1
visited[r+1][c] = 1
return True
def high_right(r,c,visited):
if c -1 < 0 or r + 1 == n:
return False
if visited[r][c] == 1 or visited[r+1][c] == 1 or visited[r][c-1] == 1:
return False
visited[r][c] = 1
visited[r+1][c] = 1
visited[r][c-1] = 1
return True
def low_left(r,c,visited):
if c + 1 == m or r -1 < 0:
return False
if visited[r][c] == 1 or visited[r-1][c] == 1 or visited[r][c+1] == 1:
return False
visited[r][c] = 1
visited[r-1][c] = 1
visited[r][c+1] = 1
return True
def low_right(r,c,visited):
if c - 1 < 0 or r - 1 < 0:
return False
if visited[r][c] == 1 or visited[r-1][c] == 1 or visited[r][c-1] == 1:
return False
visited[r][c] = 1
visited[r-1][c] = 1
visited[r][c-1] = 1
return True
def solve(x,y,visited,count):
global max_num
if y == m:
y = 0
x += 1
if x == n:
max_num = max(count,max_num)
return
if high_left(x,y,visited):
solve(x,y+1,visited,count+ 2*data[x][y] + data[x][y+1] + data[x+1][y])
visited[x][y] = 0
visited[x][y+1] = 0
visited[x+1][y] = 0
if high_right(x,y,visited):
solve(x,y+1,visited,count+2*data[x][y]+ data[x][y-1] + data[x+1][y])
visited[x][y] = 0
visited[x][y-1] = 0
visited[x+1][y] = 0
if low_right(x,y,visited):
solve(x,y+1,visited,count+2*data[x][y] + data[x-1][y] + data[x][y-1])
visited[x][y] = 0
visited[x-1][y] = 0
visited[x][y-1] = 0
if low_left(x,y,visited):
solve(x,y+1,visited,count+2*data[x][y] + data[x-1][y] + data[x][y+1])
visited[x][y] = 0
visited[x-1][y] = 0
visited[x][y+1] = 0
solve(x,y+1,visited,count)
visited = [[0] * m for _ in range(n)]
solve(0,0,visited,0)
print(max_num)
※ 회고
첫 번째 착각
처음에는 이중 포문을 돌면서 배열 좌표 하나하나 dfs를 돌라했었다. 이럴 경우 이전 좌표에 대해서는 고려를 못 해준다.
두 번째 착각
dfs함수에서 좌표 이동을 할 때 재귀로 인해 자연스럽게 좌표 이동이 됐어야 했는데 임의로 좌표 이동을 하려고 했었다.