문제 요약
문제 링크: https://www.acmicpc.net/problem/12850
숭실대학교 캠퍼스에는 8개의 건물이 있고, 서로 인접한 건물 사이를 이동하는 데 1분이 걸립니다. 정보과학관에서 출발하여 정확히 D분 후에 다시 정보과학관으로 돌아오는 경로의 수를 구하는 문제입니다.
건물 목록:
- 정보과학관 (시작/도착점)
- 전산관
- 미래관
- 신양관
- 한경직기념관
- 진리관
- 형남공학관
- 학생회관
입출력
입력:
| |
- D: 산책 시간 (1 <= D <= 1,000,000,000)
출력:
| |
예제:
| |
접근 개요
핵심 관찰
- 그래프 모델링: 캠퍼스를 8개의 정점과 간선으로 이루어진 그래프로 모델링
- 인접 행렬과 경로 수: 인접 행렬 A에서 A^D[i][j]는 정점 i에서 j로 정확히 D번 이동하는 경로의 수
- 행렬 거듭제곱: D가 최대 10^9이므로 O(log D) 시간에 행렬 거듭제곱 필요
캠퍼스 연결 구조
| |
인접 리스트:
- 정보과학관(0): 전산관(1), 미래관(2)
- 전산관(1): 정보과학관(0), 미래관(2), 신양관(3)
- 미래관(2): 정보과학관(0), 전산관(1), 신양관(3), 한경직기념관(4)
- 신양관(3): 전산관(1), 미래관(2), 한경직기념관(4), 진리관(5)
- 한경직기념관(4): 미래관(2), 신양관(3), 진리관(5), 형남공학관(6)
- 진리관(5): 신양관(3), 한경직기념관(4), 학생회관(7)
- 형남공학관(6): 한경직기념관(4), 학생회관(7)
- 학생회관(7): 진리관(5), 형남공학관(6)
알고리즘 설계
행렬 거듭제곱 원리
인접 행렬 A에서:
- A[i][j] = 1이면 i와 j가 직접 연결됨
- A^k[i][j] = i에서 j로 정확히 k번 이동하는 경로의 수
증명 (귀납법):
- k=1: A^1[i][j] = A[i][j] (정의)
- k->k+1: A^(k+1)[i][j] = sum(A^k[i][m] * A[m][j]) for all m
- 이는 i에서 m까지 k번 이동 후, m에서 j로 1번 이동하는 모든 경우의 합
빠른 거듭제곱
| |
복잡도 분석
- 시간 복잡도: O(8^3 * log D) = O(512 * log D)
- 행렬 곱셈: O(8^3)
- 거듭제곱 횟수: O(log D)
- 공간 복잡도: O(8^2) = O(64) - 행렬 저장
구현
| |
코너 케이스 체크리스트
| 케이스 | 설명 | 처리 |
|---|---|---|
| D=1 | 최소 입력 | 정보과학관에서 1분 후 돌아올 수 없음 (0) |
| D=2 | 왕복 가능 | 전산관 왕복 또는 미래관 왕복 (2가지) |
| D=10^9 | 최대 입력 | 행렬 거듭제곱으로 O(log D)에 처리 |
| 홀수 D | 패리티 | 정상 처리 (일부 D에서는 0일 수 있음) |
검증 (D=2)
정보과학관(0)에서 시작:
- 0 -> 1 -> 0 (전산관 왕복)
- 0 -> 2 -> 0 (미래관 왕복)
총 2가지 경로 -> A^2[0][0] = 2 ✓
제출 전 체크
- 모듈로 연산: 모든 곱셈 후 MOD 적용
- 오버플로우: long long 사용
- 행렬 초기화: 인접 행렬 정확히 입력
- 단위 행렬: 거듭제곱 시작 시 항등원 사용
- 비트 연산: n & 1로 홀수 판별
관련 개념
행렬 거듭제곱 활용 사례
- 피보나치 수열: F(n)을 O(log n)에 계산
- 그래프 경로 수: 정확히 k번 이동하는 경로 수
- 선형 점화식: DP 점화식의 빠른 계산
- 마르코프 체인: 상태 전이 확률 계산
참고자료
- SCCC 2016 Summer Contest - 숭실대학교 프로그래밍 동아리 대회
- 행렬 거듭제곱: 분할 정복을 이용한 O(log n) 계산
- 그래프 이론: 인접 행렬과 경로 수의 관계
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 최소 입력 | N=1 또는 빈 입력 | 반복문 범위·예외 처리 확인 |
| 오버플로우 | 답이 $2^{31}$ 초과 가능 | long long (C++) 등 사용 |
![Featured image of post [Algorithm] C++ 백준 12850번 본대 산책2](/post/algorithm/2025-12-04-boj-12850-campus-walk-matrix-exponentiation-cpp-solution/wordcloud_hu_241a2a61a52ac380.webp)
![[Algorithm] C++ 백준 2709번: 가장 작은 K](/post/algorithm/2025-12-08-boj-2709-smallest-k-last-digits-1-2-cpp-solution/wordcloud_hu_9737a176fd48c4c9.webp)
![[Algorithm] C++ 백준 12844번: XOR](/post/algorithm/2025-12-04-boj-12844-xor/wordcloud_hu_344941b860739c59.webp)
![[Algorithm] C++ 백준 12850번 본대 산책2](/post/algorithm/2025-12-04-boj-12850-campus-walk-matrix-exponentiation-cpp-solution/wordcloud_hu_8602c2af7cc44fc0.webp)
![[Algorithm] C++ 백준 13182번 제비](/post/algorithm/2025-12-04-boj-13182-lottery-draw-expectation-cpp-solution/wordcloud_hu_1623058451cb449c.webp)
![[Algorithm] C++ 백준 16313번: Janitor Troubles](/post/algorithm/2025-12-04-boj-16313-janitor-troubles-geometry-brahmagupta-cpp-solution/wordcloud_hu_f1bb0964a165d5b9.webp)
![[Algorithm] C++ 백준 12925번: Numbers](/post/algorithm/2026-01-30-boj-12925-numbers-matrix-exponentiation-cpp-solution/wordcloud_hu_c254298302da6b9f.webp)
![[Algorithm] C++ 백준 17682번 Tents](/post/algorithm/2025-12-04-boj-17682-tents-combinatorics-cpp-solution/wordcloud_hu_b137435f477ae90e.webp)
![[Algorithm] C++ 백준 11869번: 님블](/post/algorithm/2025-12-02-boj-11869-nimble-game-theory-cpp-solution/wordcloud_hu_a43d6fb95b7f88f8.webp)
![[Algorithm] C++ 백준 14289번: 본대 산책 3](/post/algorithm/2026-01-02-boj-14289-bondae-walk-3-matrix-exponentiation-cpp-solution/wordcloud_hu_d4b90edc889f3796.webp)
![[Algorithm] C++ 백준 1210번: 마피아 - 정점 분할 최소 컷](/post/algorithm/2025-08-14-boj-1210-mafia-cpp-solution/wordcloud_hu_67a0779717facab1.webp)