[파이썬] 백준 12100번 2048 (Easy)
작성:
백준 #12100 2048 (Easy)
# 출력: 최대 5번 이동시켜서 얻을 수 있는 가장 큰 블록
# 체크할 조건
# NxN
# 1 <= N <= 20
# 0은 빈 칸
# 4방향 중복순열 - 4 ** 5 == 1024가지 경우.
# 백트래킹.
# 1. 왼쪽 방향으로의 블록 이동 & 병합
# (board, N) -> None
# 2. 방향 전환 (회전)
# (board, direc) -> board
# 왼쪽 방향으로 이동 -> 회전안함 (0)
# 오른쪽 방향으로 이동 -> 좌우반전 (1)
# 위쪽 방향으로 이동 -> 반시계 90도 (2)
# 아래쪽 방향으로 이동 -> 시계 90도 (3)
# 연산 후 되돌리기 (0 X, 1 - 1, 2 - 3, 3- 2)
# 3. 가장 큰 블록 값 갱신
def move(board, N):
for i in range(N):
j = merged = now = 0
while j < N:
while j < N and not board[i][j]:
j += 1
if j == N: break
board[i][now] = board[i][j]
if now < j: board[i][j] = 0
if now == 0:
now += 1
else:
if board[i][now-1] == board[i][now] and merged < now:
board[i][now-1] *= 2
board[i][now] = 0
merged = now
else:
now += 1
j += 1
def rotate(board, d, N):
if d == 1:
for i in range(N):
board[i].reverse()
elif d == 2:
for i in range(N//2):
for j in range((N+1)//2):
board[i][j], board[N-1-j][i], board[N-1-i][N-1-j], board[j][N-1-i] \
= board[j][N-1-i], board[i][j], board[N-1-j][i], board[N-1-i][N-1-j]
elif d == 3:
for i in range(N//2):
for j in range((N+1)//2):
board[i][j], board[N-1-j][i], board[N-1-i][N-1-j], board[j][N-1-i] \
= board[N-1-j][i], board[N-1-i][N-1-j], board[j][N-1-i], board[i][j]
return board
def maxblock(board, N):
global result
for i in range(N):
for j in range(N):
if board[i][j] > result:
result = board[i][j]
def BT(board, N, depth):
if depth == 5:
maxblock(board, N)
return
for i in range(4):
next_board = [lst[:] for lst in board] # deepcopy
rotate(next_board, i, N)
move(next_board, N)
if i == 1:
rotate(next_board, i, N)
elif i == 2:
rotate(next_board, 3, N)
elif i == 3:
rotate(next_board, 2, N)
BT(next_board, N, depth+1)
def solution(N):
field = [list(map(int, input().split())) for i in range(N)]
BT(field, N, 0)
print(result)
if __name__ == '__main__':
result = -1
solution(int(input()))
- 참고: 2차원 배열 deepcopy 모듈 이용 복사 vs 슬라이싱 이용한 복사 시간차이
- 652ms vs 352ms
댓글남기기