-
백준 17825번 주사위 윷놀이 (Python)알고리즘 2023. 10. 13. 10:30728x90반응형SMALL
문제에서 주어진 게임판에서 주사위 윷놀이를 하는 게임입니다.
- 시작 칸에서 말 4개가 출발합니다.
- 말은 게임판에 그려진 화살표대로 이동할 수 있습니다. 단, 파란색 칸에서 출발하면 파란색 화살표를 타야합니다.
- 말이 도착 칸에 도달하면 주사위에 나온 수와 관계 없이 이동을 마칩니다.
- 게임은 10개의 턴으로 진행됩니다. 매 턴마다 1~5가 적혀있는 5면체 주사위를 굴리고, 도착 칸에 있지 않은 말을 하나 골라 주사위에 나온 수만큼 이동시킵니다.
- 말이 이동을 마치는 칸에 다른 말이 있으면 그 말을 고를 수 없습니다. 단, 이동을 마치는 칸이 도착 칸이면 고를 수 있습니다.
- 말이 이동을 마칠 때마다 적혀있는 수가 점수에 추가됩니다.
주사위에서 나오는 수 10개를 미리 알고 있을 때, 구할 수 있는 점수의 최대값을 구하는 문제입니다.
풀이
0. 변수, 맵 재구성
dices # 미리 알고 있는 주사위 score # 각 칸마다 점수 answer # 최대 점수 값
맵 재구성 출발 지점을 인덱스 0으로 두고 도착 지점의 인덱스를 32로 총 칸의 개수가 33개입니다.
각 칸마다 인덱스를 붙여주었습니다(동그라미 안에 숫자가 인덱스입니다). 가장 바깥쪽의 칸들이 점수가 2씩 증가하는 형태로 이어져있어 우선 바깥쪽에 먼저 인덱스를 붙여주었습니다. 그 다음, 5에서 시작하는 경우, 10에서 시작하는 경우 15에서 시작하는 경우로 차례대로 번호를 매겨준 다음 도착지점까지 인덱스를 붙여주었습니다.
1. 칸 이동시 주의할 점
이동 시 주의해야 될 칸들을 살펴보겠습니다. 주사위의 크기는 5이므로 최대 5칸 앞으로 갔을 때, 제가 정해준 칸들의 번호가 뒤바뀌는 경우 주의를 해야합니다.
다음과 같은 칸들에서 주의해야 합니다.
- 5번에서 출발하는 경우, 20~22번에서 출발하는 경우
- 10번에서 출발하는 경우, 23~24번에서 출발하는 경우
- 16~19번에서 출발하는 경우
위와 같은 경우 주사위로 인해 인덱스가 1씩 증가하는 형태가 아닌 갑자기 바뀌는 형태가 되므로 위의 조건이 나타나면 현재 위치를 잘 조정해줄 수 있도록 했습니다.
2. 인덱스 바뀔 시, 위치 변경 방법
인덱스가 1씩 증가하는 순서가 아닌 갑자기 바뀌는 경우 인덱스를 조정해주도록 하겠습니다.
def getStartPos(pos): if pos == 5: return 19 elif pos == 10: return 22 elif pos == 15: return 24 else: return pos ... pos = horse[j] startPos = getStartPos(pos) newPos = startPos+dice if (pos == 5 or 20 <= pos <= 22) and newPos > 22: newPos += 5 elif (pos == 10 or 23 <= pos <= 24) and newPos > 24: newPos += 3 elif 16 <= pos <= 19 and newPos > 19: newPos += 11 if newPos > 32: newPos = 32 if newPos != 32 and newPos in horse: continue
현재 말의 위치를 pos에 저장하고 시작 지점에 대한 정보를 얻어올 수 있도록 했습니다.
파란색 칸인 5, 10, 15 위치에 있을 때에는 다음 칸의 인덱스가 확 바뀌게 되므로 getStartPos를 통해 각각 19, 22, 24에서 시작하도록 지정해주었습니다. 나머지 칸들은 자신의 위치에서 시작하도록 했습니다.
이 후 각 조건마다 (시작 지점 + 주사위)가 지정된 범위를 넘어갈 경우 게임판에 맞는 위치로 이동할 수 있도록 했습니다.
또한, 말이 도착 지점에 도달하면 더 이상 진행되지 않도록 해주었습니다. 그리고 이동하려는 지점에 말이 이미 있다면 이동하지 못하도록 했습니다.
3. 최대값 구하기
말의 개수가 4개, 주사위를 10번 던져서 이동을 하게 되므로 모든 경우의 수는 2^20으로 진행을 해도 괜찮은 수준으로 생각하여 dfs로 모든 경우의 수를 구해보도록 했습니다.
def dfs(i, total, horse): global answer if i == 10: answer = max(answer, total) return dice = dices[i] for j in range(4): pos = horse[j] startPos = getStartPos(pos) newPos = startPos+dice if (pos == 5 or 20 <= pos <= 22) and newPos > 22: newPos += 5 elif (pos == 10 or 23 <= pos <= 24) and newPos > 24: newPos += 3 elif 16 <= pos <= 19 and newPos > 19: newPos += 11 if newPos > 32: newPos = 32 if newPos != 32 and newPos in horse: continue newTotal = total+score[newPos] newHorse = horse[:] newHorse[j] = newPos dfs(i+1, newTotal, newHorse) dfs(0, 0, [0, 0, 0, 0]) print(answer)
i는 현재 턴의 번호, total은 현재까지 점수, horse는 현재 말들의 위치를 담은 리스트입니다.
10개의 주사위를 모두 확인한 경우 정답과 비교하여 최대값을 구할 수 있도록 했습니다.
말이 이동하려는 지점에 다른 말이 없을 경우에 새로운 점수와 새로운 말 위치를 구한 뒤 dfs를 실행해주도록 했습니다.
모든 실행이 끝나고 정답을 출력해주도록 했습니다.
해결
이번 문제는 조금 빠르게 끝내 다행이었던 것 같습니다.
17825번: 주사위 윷놀이
주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다. 처음에는 시작 칸에 말 4개가 있다. 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면
www.acmicpc.net
반응형LIST'알고리즘' 카테고리의 다른 글
백준 알고리즘 풀이 모음 14590, 2469, 1107 (Feat Python) (3) 2023.11.22 백준 23289번 온풍기 안녕! (Python) (0) 2023.10.14 백준 17822번 원판 돌리기 (Python) (1) 2023.10.12 백준 21611번 마법사 상어와 블리자드 (Python) (1) 2023.10.11 백준 14890 경사로 (Python) (1) 2023.10.10