Algorithm/PS
[코드트리][Python] 삼성 SW 역량테스트 2024 상반기 오전 1번 문제 - 고대 문명 유적 탐사
행복한띠용이
2024. 10. 12. 02:09
728x90
📚 문제
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
말했다시피 삼성 문제는 호흡이 길기에 단계를 잘 나누어 풀자.
💡 풀이 과정
- def 탐사 진행()
1-1. ((x, y 기준 3 * 3 회전) * 3) * 9
1-2. def 유물 획득 가치 계산
1-3. 최대 가치 방법 선택 - def 유물 획득()
- def 새로운 조각 생성()
3-1 def 유물 획득() 후 반복 - 5. 1 ~ 4 반복
- 1 ~ 3 단계를 반복하는 과정으로 봤다.
- 5 * 5 형태이기 때문에 9가지 중심에 대해서 3가지 회전 각도에 대해서 모두 탐색한다.
- K 도 10 이하이기 때문에 완전 탐색한다.
- 동일한 숫자 N 개 이상임을 판별하기 위해서는 DFS 를 사용하였다.
📌 포인트
- 25칸 모두에 대해서 DFS 를 진행한다. 이때 이미 value 를 계산한 칸은 DFS 를 진행하면 안되기에 이중포문 밖에서의 visited 가 필요하다.
- 90도, 180도 270 도 회전은 90도를 1번, 2번, 3번 사용한 것으로 보았다.
- 회전 후 최대 가치 계산 시 Deepcopy 를 사용했기에 최대 가치의 회전을 실제 map 에 적용하는 함수가 필요했다.
- 행과 열에 대한 우선순위를 정확하게 파악하고 헷갈리지 말자.
💻 코드
# https://www.codetree.ai/training-field/frequent-problems/problems/ancient-ruin-exploration/description?page=1&pageSize=5
"""
1. def 탐사 진행()
1-1. ((x, y 기준 3 * 3 회전) * 3) * 9
1-2. def 유물 획득 가치 계산
1-3. 최대 가치 방법 선택
2. def 유물 획득()
3. def 새로운 조각 생성()
4. def 유물 획득()
---
5. 1 ~ 4 반복
"""
import sys
from copy import deepcopy
input = sys.stdin.readline
K, M = map(int, input().split())
site = [list(map(int, input().split())) for _ in range(5)]
next_number = list(map(int, input().split()))
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
new_index = 0
def calculate_value(board):
total_remove_list = []
value = 0
visited2 = [[False] * 5 for i in range(5)]
for i in range(5):
for j in range(5):
if visited2[i][j]:
continue
stack = []
target = board[i][j]
stack.append([i, j])
visited = [[False] * 5 for i in range(5)]
cnt = 0
remove_list = []
while stack:
x, y = stack.pop()
if x < 0 or x >= 5 or y < 0 or y >= 5:
continue
if visited[x][y]:
continue
visited[x][y] = True
if board[x][y] == target:
cnt += 1
remove_list.append([x, y])
for k in range(4):
nx = x + dx[k]
ny = y + dy[k]
stack.append([nx, ny])
if cnt >= 3:
value += cnt
total_remove_list.extend(remove_list)
for x, y in remove_list:
visited2[x][y] = True
return value, total_remove_list
def rotate_site(x, y, degree):
copy_site = deepcopy(site)
for _ in range(degree):
temp = copy_site[x - 1][y]
copy_site[x - 1][y] = copy_site[x][y - 1]
copy_site[x][y - 1] = copy_site[x + 1][y]
copy_site[x + 1][y] = copy_site[x][y + 1]
copy_site[x][y + 1] = temp
temp = copy_site[x - 1][y + 1]
copy_site[x - 1][y + 1] = copy_site[x - 1][y - 1]
copy_site[x - 1][y - 1] = copy_site[x + 1][y - 1]
copy_site[x + 1][y - 1] = copy_site[x + 1][y + 1]
copy_site[x + 1][y + 1] = temp
return calculate_value(copy_site)
def rotate_real_site(x, y, degree):
for _ in range(degree):
temp = site[x - 1][y]
site[x - 1][y] = site[x][y - 1]
site[x][y - 1] = site[x + 1][y]
site[x + 1][y] = site[x][y + 1]
site[x][y + 1] = temp
temp = site[x - 1][y + 1]
site[x - 1][y + 1] = site[x - 1][y - 1]
site[x - 1][y - 1] = site[x + 1][y - 1]
site[x + 1][y - 1] = site[x + 1][y + 1]
site[x + 1][y + 1] = temp
def exploration():
max_value = 0
max_index_degree = []
remove_list = []
for k in range(1, 4):
for j in range(1, 4):
for i in range(1, 4):
v, r_l = rotate_site(i, j, k)
if max_value < v:
max_value = v
max_index_degree = [i, j, k]
remove_list = r_l
if max_value == 0:
return max_value
rotate_real_site(max_index_degree[0], max_index_degree[1], max_index_degree[2])
fill_site(remove_list)
v, rl = calculate_value(site)
while v != 0:
fill_site(rl)
max_value += v
v, rl = calculate_value(site)
return max_value
def fill_site(rl):
global new_index, site
rl.sort(key=lambda x: (x[1], -x[0]))
for x, y in rl:
site[x][y] = next_number[new_index]
new_index += 1
def solv():
result = []
for _ in range(K):
value = exploration()
if value == 0:
break
result.append(value)
print(" ".join(map(str, result)))
solv()
728x90