https://www.acmicpc.net/problem/23083
문제
이세계의 승연이는 꿀벌이다.
승연이가 사는 벌집은 조금 특이한 구조로 되어있다. 벌집은 행 열의 격자로 이루어져 있고, 각 칸은 정육각형 모양이다. 같은 행에 위치한 두 칸을 비교했을 때, 짝수 번째 열의 칸은 홀수 번째 열의 칸보다 반 칸 아래에 위치해 있다. 아래 그림은 3행 4열의 격자로 이루어진 벌집의 예시이다.
두 육각형 칸이 하나의 변을 공유하고 있다면 서로 인접하다고 한다. 육각형 칸의 각 변에는 인접한 칸으로 이동할 수 있는 문이 있는데, 벌집 내 교통 정리를 위해 각 칸에서는 아래쪽, 오른쪽 위, 오른쪽 아래 칸으로만 이동할 수 있다. 또, 벌집에는 구멍 칸이 있을 수도 있는데, 구멍 칸으로는 이동할 수 없다.
승연이는 최근 꿀벌들 사이에 급속도로 전염되고 있는 변이 바이러스를 피하기 위해 벌집콕 생활을 하고 있다. 심심함이 극에 달한 승연이는 벌집의 1행 1열 칸에서 행 열 칸까지 바깥으로 나가지 않고 이동하는 경로의 개수가 알고 싶어 졌다.
자가 격리 중인 승연이가 더 이상 답답하지 않도록 경로의 개수를 세서 알려주자!
입력
첫째 줄에 , 이 공백으로 구분되어 주어진다.
다음 줄에는 구멍 칸의 개수 가 주어진다.
이어서 개 줄에 구멍 칸의 정보 , 가 공백으로 구분되어 주어진다. 이는 번째 구멍 칸이 행 열에 존재함을 뜻한다. 모든 구멍 칸의 위치는 서로 다르다.
1행 1열 칸 또는 행 열 칸이 구멍인 경우는 없음이 보장된다.
출력
벌집의 1행 1열 칸에서 행 열 칸으로 이동하는 경로의 개수를 로 나눈 나머지를 출력한다.
풀이(시간 초과)
Code(시간 초과)
import sys
from collections import defaultdict
input = sys.stdin.readline
ans = 0
def solution(n, m, empty) :
# 1. 그래프 생성
dp = [[0 for _ in range(m+1)] for _ in range(n+1)]
# 2. 초기값 설정
dp[1][1] = 1
# 3. 구멍 위치 딕셔너리 생성
empty_dict = defaultdict(int)
for x, y in empty :
empty_dict[(x, y)] = True
# 4.
for y in range(1, m+1) :
for x in range(1, n+1) :
if empty_dict[(x, y)] : continue
# 방향 인덱스 생성
dirs = [(-1, 1), (0, 1), (1, 0)] if y % 2 != 0 else [(0, 1), (1, 1), (1, 0)]
for dir_x, dir_y in dirs :
nx, ny = x + dir_x, y + dir_y
# 예외 처리
if nx < 1 or nx > n or ny < 1 or ny > m or empty_dict[(nx, ny)] : continue
dp[nx][ny] += dp[x][y]
# 5. 결과 출력
print(dp[n][m])
if __name__ == "__main__" :
n, m = map(int, input().split())
k = int(input())
empty = [list(map(int, input().split())) for _ in range(k)]
solution(n, m, empty)
풀이
Code
import sys
from collections import defaultdict
input = sys.stdin.readline
ans = 0
def solution(n, m, empty) :
# 1. 그래프 생성
dp = [[0 for _ in range(m+1)] for _ in range(n+1)]
# 2. 초기값 설정
dp[1][1] = 1
# 3. 구멍 위치 딕셔너리 생성
empty_dict = defaultdict(int)
for x, y in empty :
empty_dict[(x, y)] = True
# 4.
for y in range(1, m+1) :
for x in range(1, n+1) :
# 빈 칸일 경우 건너뛰기
if empty_dict[(x, y)] : continue
# 열에 따른 방향 인덱스 생성
dirs = [(-1, 1), (0, 1), (1, 0)] if y % 2 != 0 else [(0, 1), (1, 1), (1, 0)]
for dir_x, dir_y in dirs :
nx, ny = x + dir_x, y + dir_y
# 예외 처리
if nx < 1 or nx > n or ny < 1 or ny > m or empty_dict[(nx, ny)] : continue
# 다음 인덱스에 현재 값 더해주기
dp[nx][ny] += dp[x][y]
# 5. 결과 출력
print(dp[n][m] % (10**9 + 7))
if __name__ == "__main__" :
n, m = map(int, input().split())
k = int(input())
empty = [list(map(int, input().split())) for _ in range(k)]
solution(n, m, empty)
'Coding Test > Baekjoon' 카테고리의 다른 글
[Python/BOJ] 20055. 컨베이어 벨트 위의 로봇 (0) | 2023.10.07 |
---|---|
[Python/BOJ] 24391. 귀찮은 해강이 (1) | 2023.10.06 |
[Python/BOJ] 1527. 금민수의 개수 (1) | 2023.10.06 |
[Python/BOJ] 1189. 컴백홈 (0) | 2023.10.04 |
[Python/BOJ] 11725. 트리의 부모 찾기 (0) | 2023.09.29 |