https://www.acmicpc.net/problem/23288
23288번: 주사위 굴리기 2
크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼
www.acmicpc.net
<문제 요약>
- 크기가 N*M 지도가 존재, 주사위를 K번 이동
- 주사위에는 1-6까지 숫자가 적혀있음. 초기 주사위의 이동방향은 동쪽
- 주사위가 이동 방향으로 한칸 굴러감, 만약 이동 방향으로 갔을 때 지도를 이탈한다면 이동 방향을 반대(180도)로
한 후 움직임
- 주사위가 도착한 칸에 대한 점수를 획득
- 점수는 해당 칸에서 동서남북으로 이동할만큼 이동, 이 때 해당칸과 숫자가 같은 칸으로만 이동가능
- 칸에 적힌 정수 B, 이동 가능한 칸 C일때, 점수 = B*C
- 사위의 아랫면에 있는 정수 a와 칸에 있는 정수 b를 비교해서 이동 방향 결정
# a > b , 시계방향 90도
# a < b, 반시계 방향 90도
# a = b, 이동 방향 변화 없음
<주사위 회전> - 참고
https://it-hyorim.tistory.com/154
[백준-골드4] 14499번 주사위 굴리기 (구현, 파이썬)
https://www.acmicpc.net/problem/14499 14499번: 주사위 굴리기 첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의..
it-hyorim.tistory.com
<내 코드>
- rolling_dice(d) : 방향 d로 주사위가 굴러간 후 주사위의 상태를 변화 시킴
- bfs(x,y)
- 현재 주사위가 있는 위치에서 상,하,좌,우로 칸의 번호가 같은 인접한 칸의 갯수를 파악
- 이동을 k번 반복함
- 처음 이동할 방향으로 이동을 수행
- 만약, 범위를 이탈했을 때, 방향을 반대로(180)도 회전해야함. (d+2)%4 이용
- nx, ny 변경
- rolling_dice 함수 호출해서 주사위 상태 변화시킴
- b는 이동한 칸에 적힌 정수, c는 bfs로 인접한칸의 갯수 파악(현재 칸도 포함이므로 cnt=1로 초기화 후 시작)
- score에 점수를 더해줌
- 방향 재설정
- 주사위의 바닥에 적힌 숫자와 현재 칸에 적힌 숫자를 비교해서 방향을 변경하거나 유지함
- x, y 업데이트해서 현재 위치 반영
import sys
import copy
from collections import deque
input = sys.stdin.readline
n, m, k = map(int, input().split())
maps = []
for _ in range(n):
maps.append(list(map(int, input().split())))
# 동, 남, 서, 북 순서 -> 시계 방향
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
dice = [i for i in range(1,7)] #초기 주사위 칸마다 숫자가 들어 있음
def rolling_dice(d):
temp = copy.deepcopy(dice)
if d == 0: #동쪽
dice[0] = temp[3]
dice[2] = temp[0]
dice[3] = temp[5]
dice[5] = temp[2]
elif d == 1: #남쪽
dice[0] = temp[1]
dice[1] = temp[5]
dice[4] = temp[0]
dice[5] = temp[4]
elif d == 2: #서쪽
dice[0] = temp[2]
dice[2] = temp[5]
dice[3] = temp[0]
dice[5] = temp[3]
else: #북쪽
dice[0] = temp[4]
dice[1] = temp[0]
dice[4] = temp[5]
dice[5] = temp[1]
def bfs(x,y):
global cnt
queue = deque()
queue.append([x,y])
visited[x][y] = True
num = maps[x][y]
while queue:
x, y = queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<n and 0<=ny<m and not visited[nx][ny]:
if maps[nx][ny] == num:
cnt+=1
visited[nx][ny] = True
queue.append([nx,ny])
return cnt
x, y = 0, 0
d = 0
score = 0
for kk in range(k):
cnt = 1
visited = [[False]*m for _ in range(n)]
nx = x + dx[d]
ny = y + dy[d]
if not(0<=nx<n and 0<=ny<m): #범위 이탈
d = (d+2)%4 #반대 방향 회전 (180도)
nx = x + dx[d]
ny = y + dy[d]
rolling_dice(d) #주사위 굴러감
b = maps[nx][ny]
c = bfs(nx, ny)
score += (b*c)
# 방향 재 설정
if dice[5] > maps[nx][ny]: #주사위 아랫면 숫자가 해당 칸 보다 클때
d = (d+1) % 4 # 시계방향 90도 회전
elif dice[5] < maps[nx][ny]:
d = (d-1) % 4 # 반시계 방향 90도 회전
x, y = nx, ny #현재 위치 업데이트
print(score)
'알고리즘 > 삼성' 카테고리의 다른 글
[백준-골드3] 19238번 스타트 택시(BFS, 구현, 파이썬) (0) | 2022.04.15 |
---|---|
[백준-골드4] 14499번 주사위 굴리기 (구현, 파이썬) (0) | 2022.04.12 |
[백준-골드1] 21611번 마법사 상어와 블리자드 (구현, pypy3) (0) | 2022.04.11 |
[백준-실버1] 21608번 상어 초등학교(구현, 파이썬) (0) | 2022.04.04 |
[백준-골드2] 21609번 상어 중학교(BFS, 구현, 파이썬) (0) | 2022.04.04 |