728x90
# 소요 시간 : 2시간
# 접근 방법
- 설계를 대충했더니 디버깅 하기 힘들었던 문제였다.
- 마주했던 큰 문제 2개는 new_arr과 temp_arr 간의 얕은 복사, 90도씩 회전시킨 배열을 저장해주지 않은 점이었다.
- 우선 탐색을 시작하며, 가장 큰 1차 유물 획득 최대 값을 비교해줄 변수들을 선언해주었다.
- 또한, 원본 배열을 temp_arr에 deepcopy해주고 (0,0) 부터 (2, 2)까지를 왼쪽 상단으로 설정한 뒤 before_rotate에 복사해준다.
- 90도씩 총 3번 회전을 시키며 after_rotate에 저장해주고 before_rotate를 after로 갱신해준다.
- temp_arr에 after_rotate의 결과를 적용시켜주고 gain_score 함수를 실행해준다.
- gain_score 함수는 일반적인 bfs 함수와 동일하게 해주되, 3개 이상의 조각이 모인 경우에만 그 경로들과 개수를 return 해준다.
- 만약 1차 유물 획득이 가능하다면 유물 반복획득이 불가능 할 때까지, 빈 칸을 채우고 gain_score를 반복해주면 된다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
from collections import deque
from copy import deepcopy
def explore(e_arr):
global arr
max_cnt = 0
min_i, min_j = 5, 5
route = []
new_arr = []
min_rotate = 3
for i in range(0, 3):
for j in range(0, 3):
temp_arr = deepcopy(arr)
before_rotate = []
for r in range(0, 3):
before_rotate.append(arr[i+r][j:j+3])
for _ in range(3):
after_rotate = list(map(list, zip(*before_rotate[::-1])))
before_rotate = deepcopy(after_rotate)
r = 0
for ai in range(i, i+3):
temp_arr[ai][j:j+3] = after_rotate[r]
r += 1
cnt, temp_route = gain_score(temp_arr)
if temp_route:
if cnt > max_cnt:
min_i, min_j = i, j
max_cnt = cnt
route = temp_route
new_arr = deepcopy(temp_arr)
min_rotate = _
elif cnt == max_cnt:
if _ < min_rotate:
min_i, min_j = i, j
max_cnt = cnt
route = temp_route
new_arr = deepcopy(temp_arr)
min_rotate = _
elif _ == min_rotate:
if j < min_j:
min_i, min_j = i, j
max_cnt = cnt
route = temp_route
new_arr = deepcopy(temp_arr)
min_rotate = _
elif j == min_j:
if i < min_i:
min_i, min_j = i, j
max_cnt = cnt
route = temp_route
new_arr = deepcopy(temp_arr)
min_rotate = _
if max_cnt == 0:
return -1
else:
flag_con = True
arr = deepcopy(new_arr)
while flag_con:
flag_con = False
arr = deepcopy(fill_block(arr, route))
cnt, temp_route = gain_score(arr)
if cnt > 0:
flag_con = True
max_cnt += cnt
route = temp_route
return max_cnt
def fill_block(new_arr, route):
route.sort(key=lambda x:(x[1], -x[0]))
for fi, fj in route:
val = walls.popleft()
new_arr[fi][fj] = val
return new_arr
def gain_score(g_arr):
visited = [[False] * 5 for _ in range(5)]
temp_ans = 0
temp_r = []
for gi in range(5):
for gj in range(5):
if not visited[gi][gj]:
visited[gi][gj] = True
a, r = bfs(gi, gj, visited, g_arr[gi][gj], g_arr)
if a > 0:
for i in r:
temp_r.append(i)
temp_ans += a
if temp_ans > 0:
return [temp_ans, temp_r]
else:
return [0, 0]
def bfs(bi, bj, visit, num, b_arr):
q = deque()
q.append((bi, bj))
r = [[bi, bj]]
while q:
si, sj= q.popleft()
for d in range(4):
ni, nj = si+di[d], sj+dj[d]
if 0<=ni<5 and 0<=nj<5 and visit[ni][nj] == False and b_arr[ni][nj] == num:
q.append((ni, nj))
r.append([ni, nj])
visit[ni][nj] = True
if len(r) >= 3:
return [len(r), r]
else:
return [0, []]
di, dj = [0, 0, 1, -1], [1, -1, 0, 0]
K, M = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(5)]
w = list(map(int, input().split()))
walls = deque()
for i in w:
walls.append(i)
for _ in range(K):
score = 0
flag_stop = explore(arr)
if flag_stop == -1:
break
else:
score += flag_stop
# score = gain_score()
# if score == 0:
# break
print(score, end=' ')
728x90
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[백준 1747번] 파이썬- 소수&팰린드롬 (0) | 2024.04.28 |
---|---|
[백준 - 2559번] 파이썬 - 수열 (1) | 2024.04.28 |
[코드트리] 파이썬 - 나무 타이쿤 (0) | 2024.04.13 |
[코드트리] 파이썬 - 정육면체 한번 더 굴리기 (2) | 2024.04.12 |
[코드트리] 파이썬 - 팩맨 (0) | 2024.04.12 |