Baekjoon/구현
🥇[백준] 17406 배열 돌리기 4 (골드4)
hellosonic
2023. 7. 12. 14:32
문제요약
나의 코드 및 설명
- 너비 우선 탐색을 통해 회전할 범위에 있는 좌표를 순차적으로 방문하며, 스택을 활용해 현재 좌표 값을 저장하고, 다음 좌표 방문 시 스택에 저장된 이전 좌표 값으로 갱신한다.
- 순열 라이브러리를 통해 가능한 모든 회전 연산의 경우의 수를 탐색하여, 최소값을 구했다.
from itertools import permutations
from collections import deque
import copy
#한 줄씩 방문하면서 스택에 값을 넣고, 다음 좌표에 값을 넣는다
def bfs(sx,sy,ex,ey,stack,board):
queue = deque()
v = [[0 for _ in range(m)] for _ in range(n)]
v[sy][sx] = 1
stack.append(board[sy][sx])
queue.append((sx,sy))
i = 0
while queue:
x,y = queue.popleft()
if v[y][x] == (ex-sx) * 4:
return
nx = x + dx[i]
ny = y + dy[i]
if nx<sx or ny<sy or nx>ex or ny>ey:
i = (i+1)%4
nx = x + dx[i]
ny = y + dy[i]
queue.append((nx,ny))
stack.append(board[ny][nx]) #다음 좌표 값을 스택에 넣고
board[ny][nx] = stack.pop(0) #이전 좌표 값을 꺼내어 업데이트한다.
v[ny][nx] = v[y][x] + 1
else:
if v[ny][nx] == 1:
i = (i+1)%4
nx = x + dx[i]
ny = y + dy[i]
queue.append((nx,ny))
stack.append(board[ny][nx])
board[ny][nx] = stack.pop(0)
v[ny][nx] = v[y][x] + 1
elif v[ny][nx] == 0:
v[ny][nx] = v[y][x] + 1
queue.append((nx,ny))
stack.append(board[ny][nx])
board[ny][nx] = stack.pop(0)
#회전이 가능할 때까지 회전을 수행한다.
def rotate(a,b,e,f,cnt,board):
for i in range(cnt): #0,1
stack = []
temp = board[b+i+1][a+i]
bfs(a+i,b+i,e-i,f-i,stack,temp_arr)
board[b+i][a+i] = temp
# print()
# for j in range(n):
# print(" ".join(map(str, board[j])))
# print()
n, m, k = map(int, input().split()) #n:세로 m:가로 k:연산 개수
board = [list(map(int, input().split())) for _ in range(n)]
oper = []
for _ in range(k):
oper.append(list(map(int, input().split())))
oper_all = permutations(oper,len(oper)) #순열 : 가능한 회전연산 경우의 수
# for i in oper_all:
# print(i)
dx = [1,0,-1,0]
dy = [0,1,0,-1]
ans = 1e9
data = 0
for i in oper_all:
temp_arr = copy.deepcopy(board)
for r,c,s in i:
a = c-1-s #시작 x좌표
b = r-1-s #시작 y좌표
e = c-1+s #끝 x좌표
f = r-1+s #끝 y좌표
cnt = ((r+s) - (r-s)) // 2
rotate(a,b,e,f,cnt,temp_arr)
for j in range(n):
data = sum(temp_arr[j])
ans = min(ans, data)
# ans = 1e9
# data = 0
# for i in range(n):
# data = sum(board[i])
# ans = min(ans, data)
print(ans)
다른 코드 및 설명
- 리스트 슬라이싱을 활용한 풀이이다.
from itertools import permutations
import copy
n, m, k = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]
oper = [list(map(int, input().split())) for _ in range(k)]
ans = 1e9
for p in permutations(oper, k):
copy_a = copy.deepcopy(board)
for r, c, s in p:
r -= 1
c -= 1
for n in range(s, 0, -1):
tmp = copy_a[r-n][c+n] #끝값 저장 # 6
copy_a[r-n][c-n+1:c+n+1] = copy_a[r-n][c-n:c+n] #[1 2 3 2 5 6] >> [1 1 2 3 2 5] #오른쪽으로 가면서
for row in range(r-n,r+n): #[2 8 2 4 3] >> [8 2 4 3 3] #위로 올라가면서
copy_a[row][c-n] = copy_a[row+1][c-n]
copy_a[r+n][c-n:c+n] = copy_a[r+n][c-n+1:c+n+1] #[3 2 1 4 3] >> [2 1 4 3 3]
for row in range(r+n, r-n, -1):
copy_a[row][c+n] = copy_a[row-1][c+n]
copy_a[r-n+1][c+n] = tmp #마지막 값(오른쪽 위) 처리
for j in copy_a:
ans = min(ans, sum(j))
print(ans)
피드백
나는 너비우선탐색을 활용하여 문제를 해결했는데, 리스트 슬라이싱을 통해 간단하게 풀이할 수 있었다.