백준 온라인 저지, 구현 / 17825번: 주사위윷놀이 (파이썬 / , 백준 골드문제, 삼성 SW 기출문제)
2021. 12. 13. 19:06ㆍ알고리즘/구현
728x90
반응형
문제
주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다.
- 처음에는 시작 칸에 말 4개가 있다.
- 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면 파란색 화살표를 타야 하고, 이동하는 도중이거나 파란색이 아닌 칸에서 이동을 시작하면 빨간색 화살표를 타야 한다. 말이 도착 칸으로 이동하면 주사위에 나온 수와 관계 없이 이동을 마친다.
- 게임은 10개의 턴으로 이루어진다. 매 턴마다 1부터 5까지 한 면에 하나씩 적혀있는 5면체 주사위를 굴리고, 도착 칸에 있지 않은 말을 하나 골라 주사위에 나온 수만큼 이동시킨다.
- 말이 이동을 마치는 칸에 다른 말이 있으면 그 말은 고를 수 없다. 단, 이동을 마치는 칸이 도착 칸이면 고를 수 있다.
- 말이 이동을 마칠 때마다 칸에 적혀있는 수가 점수에 추가된다.
주사위에서 나올 수 10개를 미리 알고 있을 때, 얻을 수 있는 점수의 최댓값을 구해보자.
입력
첫째 줄에 주사위에서 나올 수 10개가 순서대로 주어진다.
출력
얻을 수 있는 점수의 최댓값을 출력한다.
예제 입력 1
1 2 3 4 1 2 3 4 1 2
예제 출력 1
190
예제 입력 2
1 1 1 1 1 1 1 1 1 1
예제 출력 2
133
예제 입력 3
5 1 2 3 4 5 5 3 2 4
예제 출력 3
214
예제 입력 4
5 5 5 5 5 5 5 5 5 5
예제 출력 4
130
접근 방법
- 주사위 윷놀이를 다음과 같은 리스트로 초기화한다.
- board = [[5의 배수가 아닌 인덱스인 경우의 맵], [5의 배수이자, 몫이 1인 경우 이동하게될 맵], [5의 배수이자, 몫이 2인 경우 이동하게될 맵], [5의 배수이자, 몫이 3인 경우 이동하게될 맵]]]
- 초기 말의 위치는 모두 [0, 0]로 초기화한다. ([5의 배수일 경우의 현재 위치를 5로 나눈 몫(5의 배수가 아니면 0), 현재 위치])
- board에서 5의 배수가 아닌 인덱스로 이동할 경우 말의 현재 위치만 변경시켜주고, 값을 더해준다.
- board에서 5의 배수인 인덱스로 이동할 경우 [5로 나눴을 때의 몫, 0]으로 말의 위치를 초기화한다.
- 말을 매번 이동시킬 때는 다음과 같은 주의사항을 지킨다.
- 1. 서로 다른 말들의 위치를 확인한 뒤, 말의 위치가 겹치지 않도록 한다.(고유한 번호를 통해 비교)
- 2. 현재위치를 기반으로 5의 배수인 인덱스로 이동할 때 말의 위치를 나타내는 리스트의 첫번째 인덱스가 0인 경우에만 말의 위치를 [5로 나눴을 때의 몫, 0]으로 초기화시키고, 그 외엔 초기화시키지 않고 현재 위치만 변경한다.
코드
# https://www.acmicpc.net/problem/17825
# 접근 방법
# 주사위 윷놀이를 다음과 같은 리스트로 초기화한다.
# board = [[5의 배수가 아닌 인덱스인 경우의 맵], [5의 배수이자, 몫이 1인 경우 이동하게될 맵], [5의 배수이자, 몫이 2인 경우 이동하게될 맵], [5의 배수이자, 몫이 3인 경우 이동하게될 맵]]]
# 초기 말의 위치는 모두 [0, 0]로 초기화한다. ([5의 배수일 경우의 현재 위치를 5로 나눈 몫(5의 배수가 아니면 0), 현재 위치])
# board에서 5의 배수가 아닌 인덱스로 이동할 경우 말의 현재 위치만 변경시켜주고, 값을 더해준다.
# board에서 5의 배수인 인덱스로 이동할 경우 [5로 나눴을 때의 몫, 0]으로 말의 위치를 초기화한다.
# 말을 매번 이동시킬 때는 다음과 같은 주의사항을 지킨다.
# 1. 서로 다른 말들의 위치를 확인한 뒤, 말의 위치가 겹치지 않도록 한다.(고유한 번호를 통해 비교)
# 2. 현재위치를 기반으로 5의 배수인 인덱스로 이동할 때 말의 위치를 나타내는 리스트의 첫번째 인덱스가 0인 경우에만 말의 위치를 [5로 나눴을 때의 몫, 0]으로 초기화시키고, 그 외엔 초기화시키지 않고 현재 위치만 변경한다.
def move_horse(horse, number, count, score):
if count == 11:
global result
result = max(score, result)
return
h = horse[number]
if h[0] == -1: # 이미 도착한 말을 움직이려할 때는 리턴
return
m = dice[count-1] # 이동 횟수 초기화
if not (h[1] + m) % 5 and not h[0] and (h[1] + m) // 5 < 4: # 이동하고자하는 곳이 5의 배수이며 h[0]의 값이 0이라면
next = [(h[1] + m) // 5, 0]
else:
if len(board[h[0]]) > h[1] + m:
next = [h[0], h[1]+m]
else:
next = [-1, -1]
# 말을 이동 시 서로 다른 말의 위치와 겹치는 지 확인
if next[0] != -1:
s = board[next[0]][next[1]]
# print(s)
for i in range(4):
h_ = horse[i]
if h_[0] != -1 and s[1] == board[h_[0]][h_[1]][1]:
return
score += s[0] # 말이 이동할 수 있는 장소일 경우 점수를 더한다.(도착지점 제외)
horse_ = [x[:] for x in horse]
horse_[number] = next
move_horse(horse_, 0, count+1, score)
move_horse(horse_, 1, count+1, score)
move_horse(horse_, 2, count+1, score)
move_horse(horse_, 3, count+1, score)
return
dice = list(map(int, input().split()))
board = [[[i * 2, i] for i in range(21)]]
board.append([[10, 5], [13, 21], [16, 22], [19, 23], [25, 29], [30, 30], [35, 31], [40, 20]])
board.append([[20, 10], [22, 24], [24, 25], [25, 29], [30, 30], [35, 31], [40, 20]])
board.append([[30, 15], [28, 26], [27, 27], [26, 28], [25, 29], [30, 30], [35, 31], [40, 20]])
horse = [[0, 0] for _ in range(4)]
result = 0
move_horse(horse, 0, 1, 0)
print(result)
728x90
반응형
'알고리즘 > 구현' 카테고리의 다른 글
백준 온라인 저지, 구현 / 14891번: 톱니바퀴 (파이썬 / , 백준 골드문제, 삼성 SW 기출문제) (0) | 2021.12.18 |
---|---|
백준 온라인 저지, 구현 / 20055번: 컨베이어벨트위의로봇 (파이썬 / , 백준 실버문제, 삼성 SW 기출문제) (0) | 2021.12.16 |
백준 온라인 저지, 구현 / 17140번: 이차원배열과연산 (파이썬 / , 백준 골드문제, 삼성 SW 기출문제) (0) | 2021.12.10 |
백준 온라인 저지, 구현 / 14500번: 테트로미노 (파이썬 / , 백준 골드문제, 삼성 SW 기출문제) (0) | 2021.12.07 |
백준 온라인 저지, 구현 / 19237번: 어른상어 (파이썬 / , 백준 골드문제, 삼성 SW 기출문제) (0) | 2021.12.06 |