https://www.acmicpc.net/problem/23288
23288번: 주사위 굴리기 2
크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼
www.acmicpc.net
# 23288 주사위 굴리기 2
def move_dice(cur_dir):
# 위로 이동
if cur_dir == 0:
temp_num = dice[0][1]
dice[0][1] = dice[1][1]
dice[1][1] = dice[2][1]
dice[2][1] = dice[3][1]
dice[3][1] = temp_num
# 왼쪽으로 이동
elif cur_dir == 1:
temp_num = dice[1][1]
dice[1][1] = dice[1][2]
dice[1][2] = dice[3][1]
dice[3][1] = dice[1][0]
dice[1][0] = temp_num
# 아래쪽으로 이동
elif cur_dir == 2:
temp_num = dice[0][1]
dice[0][1] = dice[3][1]
dice[3][1] = dice[2][1]
dice[2][1] = dice[1][1]
dice[1][1] = temp_num
# 오른쪽으로 이동
elif cur_dir == 3:
temp_num = dice[1][1]
dice[1][1] = dice[1][0]
dice[1][0] = dice[3][1]
dice[3][1] = dice[1][2]
dice[1][2] = temp_num
return
# 상 좌 하 우
dr = [-1, 0, 1, 0]
dc = [0, -1, 0, 1]
N, M, K = map(int, input().split())
grounds = [list(map(int, input().split())) for _ in range(N)]
dice = [
[0, 2, 0],
[4, 1, 3],
[0, 5, 0],
[0, 6, 0]
]
cur_r = 0
cur_c = 0
cur_dir = 3
total_score = 0
for _ in range(K):
# 1. 주사위가 이동 방향으로 한 칸 굴러간다.
tr = cur_r + dr[cur_dir]
tc = cur_c + dc[cur_dir]
if 0 <= tr < N and 0 <= tc < M:
pass
# 1-1. 만약 이동 방향에 칸이 없다면, 이동 방향을 반대로 한 다음 한 칸 굴러간다.
else:
cur_dir = (cur_dir + 2) % 4
tr = cur_r + dr[cur_dir]
tc = cur_c + dc[cur_dir]
cur_r = tr
cur_c = tc
# 주사위도 이동시킨다.
move_dice(cur_dir)
# 2. 주사위가 도착한 칸 (x, y)에 대한 점수를 획득한다.
temp_score = 0
visited = [[0] * M for _ in range(N)]
visited[cur_r][cur_c] = 1
my_num = grounds[cur_r][cur_c]
queue = [[cur_r, cur_c]]
cnt = 1
while queue:
qr, qc = queue.pop(0)
for i in range(4):
cr = qr + dr[i]
cc = qc + dc[i]
if 0 <= cr < N and 0 <= cc < M and visited[cr][cc] == 0 and grounds[cr][cc] == my_num:
visited[cr][cc] = 1
queue.append([cr, cc])
cnt += 1
total_score += (my_num * cnt)
# 3. 주사위의 아랫면에 있는 정수 A와 x, y에 있는 B를 비교해 이동 방향을 결정한다.
A = dice[3][1]
B = grounds[cur_r][cur_c]
# 3-1. A > B인 경우 이동 방향 90도 시계 방향 회전
if A > B:
cur_dir = (cur_dir - 1) % 4
# 3-2. A < B인 경우 90도 반시계방향
elif A < B:
cur_dir = (cur_dir + 1) % 4
# 3-3. A == B인 경우 변화 X
print(total_score)
예전 코드
# 23288 주사위 굴리기 2
# 상 좌 하 우
dr = [-1, 0, 1, 0]
dc = [0, -1, 0, 1]
# 반대 방향
def change_dir(cur_dir):
if cur_dir >= 2:
cur_dir -= 2
else:
cur_dir += 2
return cur_dir
# 동쪽
def move_right():
temp = dice[1][1]
dice[1][1] = dice[1][0]
dice[1][0] = dice[3][1]
dice[3][1] = dice[1][2]
dice[1][2] = temp
# 서쪽
def move_left():
temp = dice[1][1]
dice[1][1] = dice[1][2]
dice[1][2] = dice[3][1]
dice[3][1] = dice[1][0]
dice[1][0] = temp
# 북쪽
def move_up():
temp = dice[1][1]
dice[1][1] = dice[2][1]
dice[2][1] = dice[3][1]
dice[3][1] = dice[0][1]
dice[0][1] = temp
# 남쪽
def move_down():
temp = dice[1][1]
dice[1][1] = dice[0][1]
dice[0][1] = dice[3][1]
dice[3][1] = dice[2][1]
dice[2][1] = temp
def cal_score(B):
queue = [cur_pos]
visited = [[0] * M for _ in range(N)]
visited[cur_pos[0]][cur_pos[1]] = 1
cnt = 1
while queue:
qr, qc = queue.pop(0)
for i in range(4):
cr = qr + dr[i]
cc = qc + dc[i]
if 0 <= cr and cr < N and 0 <= cc and cc < M and visited[cr][cc] == 0 and grounds[cr][cc] == B:
cnt += 1
visited[cr][cc] = 1
queue.append([cr, cc])
return cnt * B
def move():
global cur_dir
# 범위 밖으로 벗어난다면 반대 방향으로
# 맨 윗줄이면서 북쪽으로 간다면
if cur_pos[0] == 0 and cur_dir == 0:
cur_dir = change_dir(cur_dir)
# 맨 아랫줄이면서 남쪽으로 간다면
elif cur_pos[0] == N - 1 and cur_dir == 2:
cur_dir = change_dir(cur_dir)
# 맨 왼쪽이면서 서쪽으로 간다면
elif cur_pos[1] == 0 and cur_dir == 1:
cur_dir = change_dir(cur_dir)
# 맨 오른쪽이면서 동쪽으로 간다면
elif cur_pos[1] == M - 1 and cur_dir == 3:
cur_dir = change_dir(cur_dir)
cur_pos[0] += dr[cur_dir]
cur_pos[1] += dc[cur_dir]
# 주사위 이동
# 동쪽
if cur_dir == 3:
move_right()
# 북쪽
elif cur_dir == 0:
move_up()
# 서쪽
elif cur_dir == 1:
move_left()
# 남쪽
elif cur_dir == 2:
move_down()
# 칸 점수 획득
B = grounds[cur_pos[0]][cur_pos[1]]
num = cal_score(B)
score[0] += num
return B
N, M, K = map(int, input().split())
grounds = [list(map(int, input().split())) for _ in range(N)]
cur_pos = [0, 0]
cur_dir = 3 # 북 서 남 동, 0, 1, 2, 3
dice = [[0] * 3 for _ 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
score = [0]
for _ in range(K):
B = move()
# 주사위 아랫면, 칸 점수 비교
if dice[3][1] > B:
# 90도 시계방향 회전
cur_dir -= 1
if cur_dir < 0:
cur_dir += 4
elif dice[3][1] < B:
# 90도 반시계방향 회전
cur_dir += 1
if cur_dir >= 4:
cur_dir -= 4
print(score[0])
'프로그래밍 > 문제풀이' 카테고리의 다른 글
[Python] 백준 23291 어항 정리 (1) | 2022.10.15 |
---|---|
[Python] 백준 23290 마법사 상어와 복제 (1) | 2022.10.15 |
[Python] 백준 23289 온풍기 안녕! (1) | 2022.10.15 |
[Python] 백준 16236 아기 상어 (0) | 2022.10.14 |
[Python] 백준 21610 마법사 상어와 비바라기 (0) | 2022.10.14 |