ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 17825번 주사위 윷놀이 (Python)
    알고리즘 2023. 10. 13. 10:30
    728x90
    반응형
    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 주사위 윷놀이

     

    17825번: 주사위 윷놀이

    주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다. 처음에는 시작 칸에 말 4개가 있다. 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면

    www.acmicpc.net

     

    반응형
    LIST

    댓글

Designed by Tistory.