코드트리 학습하기 - 알고리즘 입문 : Backtracking
# 1 : [0~i][j]
# 2 : 상하좌우
# 3 : 대각선
n = int(input())
matrix = [list(map(int, input().split())) for _ in range(n)]
bomb_m = [[0 for _ in range(n)] for _ in range(n)]
d1 = [(-2, 0), (-1, 0), (1, 0), (2, 0)] # 1번 폭탄의 피해 방향
d2 = [(-1, 0), (1, 0), (0, 1), (0, -1)] # 2번 폭탄의 피해 방향
d3 = [(-1, -1), (-1, 1), (1, -1), (1, 1)] # 3번 폭탄의 피해 방향
bomb_index = []
arr = []
ans = []
## bomb_m 초기화 함수
def init_bomb_m():
bomb_m = [[0 for _ in range(n)] for _ in range(n)]
for i in range(len(bomb_index)):
bomb_m[bomb_index[i][0]][bomb_index[i][1]] = 1
return bomb_m
## 폭탄의 피해범위 구하기
def bomb_explosion(arr):
# 변수 초기화
bomb_m = init_bomb_m()
count = len(arr)
# 폭탄 종류에 맞춰서 각 폭탄이 존재하는 인덱스에 해당 폭탄 종류가 터졌을 때의 맵 상황 bomb_m에 기록하기 (0은 빈칸, 1은 피해입은칸)
for b in range(len(arr)):
bx = bomb_index[b][0]
by = bomb_index[b][1]
if (arr[b] == 1): # 1번 폭탄
for j in range(len(d1)):
dx = d1[j][0]
dy = d1[j][1]
if (bx + dx < n and by + dy < n and bx + dx >= 0 and by + dy >= 0):
if (bomb_m[bx + dx][by + dy] == 0):
bomb_m[bx + dx][by + dy] = 1
count += 1
if (arr[b] == 2): # 2번 폭탄
for j in range(len(d2)):
dx = d2[j][0]
dy = d2[j][1]
if (bx + dx < n and by + dy < n and bx + dx >= 0 and by + dy >= 0):
if (bomb_m[bx + dx][by + dy] == 0):
bomb_m[bx + dx][by + dy] = 1
count += 1
if (arr[b] == 3): # 3번 폭탄
for j in range(len(d3)):
dx = d3[j][0]
dy = d3[j][1]
if (bx + dx < n and by + dy < n and bx + dx >= 0 and by + dy >= 0):
if (bomb_m[bx + dx][by + dy] == 0):
bomb_m[bx + dx][by + dy] = 1
count += 1
ans.append(count)
## 폭탄의 종류를 결정해서 조합을 만듦
def get_bomb_list(num):
if (num == count_b):
bomb_explosion(arr) # 만들어진 폭탄의 피해 규모 확인
return
for i in range(1, 4): # 폭탄은 1,2,3 세 종류
arr.append(i)
get_bomb_list(num + 1)
arr.pop()
return
### main 실행 부분
count_b = 0
for i in range(n):
for j in range(n):
if (matrix[i][j] == 1):
count_b += 1 # 폭탄의 개수 카운트
bomb_index.append((i, j)) # 폭탄의 인덱스 저장
bomb_m[i][j] = 1
get_bomb_list(0)
# print(ans)
print(max(ans))
계속 해왔던 Backtracking 문제처럼 구조를 잡아준다. → get_bomb_list
우선 Backtracking에 들어가기 전에 폭탄의 위치와 인덱스를 저장해준다.
이후 폭탄의 종류에 따른 조합을 Backtracking으로 get_bomb_list
에서 만들어준다.
만약 맵에 있는 폭탄의 개수만큼 조합이 만들어지면 → 해당 폭탄 조합의 피해 규모를 확인하기 위해 bomb_explosion
함수로 이동하여 검사한다.
bomb_explosion
함수에서는 각 폭탄의 종류에 맞춰서 맵의 인덱스 내부의 피해 규모를 저장해준다.
그 다음 조합의 검사를 위해서는 임시 맵을 초기화해준다. (init_bomb_m
)
모든 조합의 폭탄 피해 규모를 저장한 배열 중 최댓값이 정답으로 출력된다.
시간을 잡아먹었던 점 :
init_bomb_m
함수 생성 계기수정해보기 :
함수 → 함수
를 또 타고 들어가서 구하지 않고 그냥 한 함수로 구현해도 괜찮을 것 같다.