[BOJ] 16928. 뱀과 사다리 게임

Jimeaning·2023년 6월 25일
2

코딩테스트

목록 보기
104/143

Python3

문제

https://www.acmicpc.net/problem/16928

키워드

  • 그래프 탐색
  • 너비 우선 탐색

문제 풀이

문제 요구사항

주사위를 조작해 내가 원하는 수가 나오게 만들 수 있다면, 최소 몇 번만에 도착점에 도착할 수 있을까?

  • 보드판에는 1부터 100까지 수가 하나씩 순서대로 적혀져 있다.

  • 플레이어는 주사위를 굴려 나온 수만큼 이동해야 한다.

  • 만약 주사위를 굴린 결과가 100번 칸을 넘어간다면 이동할 수 없다.

  • 도착한 칸이 사다리면, 사다리를 타고 위로 올라간다. 뱀이 있는 칸에 도착하면, 뱀을 따라서 내려가게 된다.

  • 게임의 목표는 1번 칸에서 시작해서 100번 칸에 도착하는 것이다.

  • 게임판의 상태가 주어졌을 때, 100번 칸에 도착하기 위해 주사위를 굴려야 하는 횟수의 최솟값을 구하는 프로그램.

변수 및 함수 설명

  • n, m: 게임판에 있는 사다리의 수 N(1 ≤ N ≤ 15)과 뱀의 수 M(1 ≤ M ≤ 15)
  • x, y: 사다리의 정보 (x < y) x번 칸에 도착하면, y번 칸으로 이동한다
  • u, v: 뱀의 정보 (u > v) u번 칸에 도착하면, v번 칸으로 이동한다
  • ladder: 사다리 정보가 저장된 딕셔너리
  • snakes: 뱀 정보가 저장된 딕셔너리
  • answer: 주사위를 굴린 횟수를 저장하는 리스트
  • queue: bfs에 필요한 큐
  • visited: 방문 처리 리스트
  • pos: 현재 위치가 저장된 변수
  • nloc: 다음으로 이동할 위치가 저장되는 변수
  • bfs(): bfs 함수 구현

풀이

(입력 및 선언)

  • 사다리 수(n)와 뱀의 수(m)를 입력 받는다.
  • 딕셔너리 형태로 사다리 정보와 뱀 정보를 각각 저장한다.
  • 큐와 방문 처리 리스트, 주사위 횟수 리스트를 초기화한다.

(게임 시작)

  • 게임은 1부터 시작하므로 큐에 1을 넣고 방문 처리를 한다.
  • bfs 함수 호출

(bfs 함수)

  • 큐에 원소가 있을 때까지 반복한다
  • 큐에서 첫 번째 원소를 빼고, 현재 위치 변수에 저장한다.
  • 만약 현재 위치가 100이라면 주사위를 굴린 횟수를 출력하고 반복문을 종료한다.
  • 주사위는 총 6까지 있으므로 6번 반복한다.
  • 다음 위치는 현재 위치 + (i+1)한 값이다. (가독성을 위해 range(1, 7)대신 range(6)으로 하고 i+1을 해주었다)
  • 만약 다음 위치가 맵을 벗어난다면(1~100 사이 숫자가 아니라면) continue
  • 다음 위치가 사다리 key에 해당된다면, 다음 위치를 해당 값(value)로 저장한다.
  • 다음 위치가 뱀 key에 해당된다면, 다음 위치를 해당 값(value)로 저장한다.
  • 방문 안 한 곳일 때, 큐에 다음 위치를 넣고 방문처리를 한다.
    주사위를 굴린 횟수를 1 증가시킨다.

최종 코드

from collections import deque

n, m = map(int, input().split())

ladder = {}
snakes = {}

answer = [0 for _ in range(101)]
queue = deque([1])
visited = [0 for _ in range(101)]

# 사다리 정보 저장
for _ in range(n):
    x, y = map(int, input().split())

    ladder[x] = y

# 뱀 정보 저장
for _ in range(m):
    u, v = map(int, input().split())

    snakes[u] = v

def bfs():
    while queue:
        pos = queue.popleft()
        if pos == 100:
            print(answer[pos])
            break
        for i in range(6):
            nloc = pos + i + 1
            if nloc > 100 or nloc < 0:
                continue
            if nloc in ladder.keys():
                nloc = ladder[nloc]
            if nloc in snakes.keys():
                nloc = snakes[nloc]
            if not visited[nloc]:
                queue.append(nloc)
                visited[nloc] = 1
                answer[nloc] = answer[pos] + 1

visited[1] = 1
bfs()

(+ 23/7/14)

answer 리스트 만들지 않고 visited 활용한 코드

from collections import deque

n, m = map(int, input().split())

ladder = {}
snake = {}

visited = [0 for _ in range(101)]
queue = deque()

for _ in range(n):
    x, y = map(int, input().split())
    ladder[x] = y

for _ in range(m):
    u, v = map(int, input().split())
    snake[u] = v

def bfs():
    while queue:
        curNum = queue.popleft()
        if curNum >= 100:
            return visited[curNum] - 1
        for i in range(6):
            nNum = curNum + i + 1
            if nNum > 100 or nNum < 0:
                continue
            if nNum in ladder.keys():
                nNum = ladder[nNum]
            if nNum in snake.keys():
                nNum = snake[nNum]
            if not visited[nNum]:
                queue.append(nNum)
                visited[nNum] = visited[curNum] + 1

queue.append(1)
visited[1] = 1
print(bfs())

피드백

딕셔너리를 사용한 그래프 문제였다. 문제가 난잡한 것이 아니라서 차근히 여러 개념을 적용하고 복습하기 좋았다.
처음에는 answer을 변수로 설정했는데 최솟값이 출력되지 않아 리스트로 바꾸게 되었다.

profile
I mean

0개의 댓글