코딩테스트/삼성 기출
삼성기출, 백준 23288 주사위 굴리기2 파이썬 코드/풀이
RyanKwon
2022. 10. 9. 15:57
728x90
한시간 정도 잡고 풀었는데 한시간 반 걸렸다.
예제에 안되는 문제가 있어서 디버깅 해보니까 주사위 돌리는 과정에서 딥카피가 안돼서 오류가 나고 있었다.
해당 부분 for문으로 값을 넣어줘서 딥카피로 해결했다.
총 4개 함수를 만들어서 풀었다.
1. 이동 방향 결정 + 주사위 모양 바꾸기
2. 주사위가 이동하는 부분의 좌표 확인
3. 좌표 확인시 뒤로 되돌아가는 경우 이동방향 재결정 및 주사위모양 다시바꾸기
4. 점수계산
N, M, total = map(int, input().split())
grid = []
for i in range(N):
grid.append(list(map(int, input().split())))
dice = [[0 for i in range(3)] for j in range(4)]
dice[0][1] = 2
dice[1][0] = 4
dice[1][1] = 1
dice[1][2] = 3
dice[2][1] = 5
dice[3][1] = 6
#1회차에는 오른쪽으로 굴러감.
#점수 계산
#주사위 갈 방향 결정 -> 주사위 모습 변경 및 이동하느 좌표 리턴
RIGHT, LEFT, DOWN, UP = 0, 2, 1, 3
def roll_dice(dice, prev_dir, loc, cnt): #굴릴 방향 결정 및 주사위 모습 변경
y, x = loc[0], loc[1]
A = dice[3][1]
B = grid[y][x]
if A > B:
dir = (prev_dir + 1) % 4
elif B > A:
dir = (prev_dir + 3) % 4
else:
dir = prev_dir
tmp_dice = [[0 for i in range(3)] for j in range(4)]
for i in range(4):
for j in range(3):
tmp_dice[i][j] = dice[i][j]
if cnt == 0:
dir = RIGHT
if dir == RIGHT: #동
dice[1][0] = tmp_dice[3][1]
dice[1][1] = tmp_dice[1][0]
dice[1][2] = tmp_dice[1][1]
dice[3][1] = tmp_dice[1][2]
elif dir == LEFT: #서
dice[1][0] = tmp_dice[1][1]
dice[1][1] = tmp_dice[1][2]
dice[1][2] = tmp_dice[3][1]
dice[3][1] = tmp_dice[1][0]
elif dir == DOWN: #남
for i in range(4):
dice[i][1] = tmp_dice[(i + 3) % 4][1]
else: #북
for i in range(4):
dice[i][1] = tmp_dice[(i + 1) % 4][1]
return dice, dir
def re_roll_dice(dice, prev_dir, loc): #주사위 방향 반대 설정 및 주사위 모습 변경
dir = (prev_dir + 2) % 4
tmp_dice = [[0 for i in range(3)] for j in range(4)]
for _ in range(2):
for i in range(4):
for j in range(3):
tmp_dice[i][j] = dice[i][j]
if dir == RIGHT: #동
dice[1][0] = tmp_dice[3][1]
dice[1][1] = tmp_dice[1][0]
dice[1][2] = tmp_dice[1][1]
dice[3][1] = tmp_dice[1][2]
elif dir == LEFT: #서
dice[1][0] = tmp_dice[1][1]
dice[1][1] = tmp_dice[1][2]
dice[1][2] = tmp_dice[3][1]
dice[3][1] = tmp_dice[1][0]
elif dir == DOWN: #남
for i in range(4):
dice[i][1] = tmp_dice[(i + 3) % 4][1]
else: #북
for i in range(4):
dice[i][1] = tmp_dice[(i + 1) % 4][1]
return dice, dir
def new_loc(dice, loc, dir): #이동좌표리턴
y, x = loc
ny, nx = y, x
if dir == RIGHT: #동
nx = x + 1
if nx >= M:
nx = x - 1
dice, dir = re_roll_dice(dice, dir, loc)
elif dir == LEFT: #서
nx = x - 1
if nx < 0:
nx = x + 1
dice, dir = re_roll_dice(dice, dir, loc)
elif dir == DOWN: #남
ny = y + 1
if ny >= N:
ny = y - 1
dice, dir = re_roll_dice(dice, dir, loc)
else: #북
ny = y - 1
if ny < 0:
ny = y + 1
dice, dir = re_roll_dice(dice, dir, loc)
return dice, dir, [ny, nx]
def calculation(loc):
y, x = loc
B = grid[y][x]
stack = [loc]
visited = [[0 for i in range(M)] for j in range(N)]
cnt = 0
# print(loc)
while stack:
y, x = stack[-1]
stack = stack[:-1]
if visited[y][x] == 1:
continue
visited[y][x] = 1
cnt += 1
for dy, dx in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
ny, nx = y + dy, x + dx
if ny >= N or ny < 0 or nx >= M or nx < 0:
continue
if grid[ny][nx] == B and visited[ny][nx] == 0:
stack.append([ny, nx])
return cnt * B
dir = RIGHT
loc = [0, 0]
answer = 0
for cnt in range(total):
dice, dir = roll_dice(dice, dir, loc, cnt)
dice, dir, loc = new_loc(dice, loc, dir)
answer += calculation(loc)
print(answer)728x90