Notice
Recent Posts
Recent Comments
Link
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- Lv. 3
- dfs
- Lv. 2
- Python
- Lv. 0
- bfs
- 깊이 우선 탐색
- 백준
- Dynamic Programming
- 프로그래머스
- Lv. 1
- SQL 고득점 KIT
- 동적계획법
- softeer
- LEVEL 2
- 파이썬
- Baekjoon
- programmers
- level 3
- 너비 우선 탐색
- 자바스크립트
- 소프티어
- join
- Java
- javascript
- 티스토리챌린지
- group by
- DP
- 오블완
- SQL
Archives
- Today
- Total
몸과 마음이 건전한 SW 개발자
백준 GOLD 4 [10830번] 행렬 제곱 {언어 : Python} 본문
728x90
문제 링크
https://www.acmicpc.net/problem/10830
정답 코드
import sys
input = sys.stdin.readline
n, b = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(n)]
optimization = dict()
# matrix의 원소가 1000이하이기 때문에 처음부터 걸러준다.
for i in range(n):
for j in range(n):
matrix[i][j] %= 1000
optimization[1] = matrix
# cal = calculation
def cal(leftM, rightM):
newM = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
for k in range(n):
newM[i][j] += (leftM[i][k] * rightM[k][j]) % 1000
newM[i][j] %= 1000
return newM
# dac = divide and conquer
def dac(depth):
if depth == 1:
return matrix
elif depth == 2:
return cal(matrix, matrix)
else:
if optimization.get(depth, 0) == 0:
if depth % 2:
optimization[depth] = cal(dac(depth//2+1), dac(depth//2))
else:
optimization[depth] = cal(dac(depth//2), dac(depth//2))
return optimization[depth]
answer = dac(b)
for a in answer:
print(*a)
풀이 방법
- 분할정복으로 풀었다.
- 만약 10제곱이라면
- 2등분해서 5 5로 나누고
- 5를 2 3으로 나누고
- 2는 1 1
- 3은 다시 2 1
- 2는 1 1
- 이렇게 나눠서 가장 깊숙한 지점부터 계산해서 올라 온다.
- 만약 n제곱이 존재하면 계산할 필요가 없이 dictionary에서 찾을 수 있도록 최적화 했다.
- 이렇게 하지 않았다면 시간초과가 걸렸을 것이다.
- 맨 처음에 1000으로 나누어 떨어뜨리는 이유
- 주어진 행렬의 원소가 1 <= elem <= 1000 이고 결과값은 원소 모두가 1000으로 나누어 떨어진 값이어야 하기 때문이다.
- 이렇게 안 하면 거듭제곱이 1이고 원소가 다 1000일 경우 틀린 값이 나오게 된다.
- 계산이 완료되면 answer에 넣고 출력하면 끝!
느낀점
- 문제를 잘 읽어도 이런 문제는 실수를 유도하는 것 같다.
- b의 값이 100,000,000,000이었기 때문에 분할 정복을 유추할 수 있었다.
- 이미 계산한 과정은 생략하고 바로 값을 찾을 수 있도록 딕셔너리에 넣는 방법을 배웠다.
728x90
'알고리즘 > 풀었지만 다시 보기' 카테고리의 다른 글
프로그래머스 [Lv. 2] 비밀 코드 해독 {언어 : JavaScript} (0) | 2025.03.23 |
---|---|
백준 GOLD 3 [15684번] 사다리 조작 {언어 : Python} (0) | 2025.01.23 |
코드트리 | HashMap / 순서를 바꾸었을 때 같은 단어 그룹화하기 {언어 : Python} [가장 작은 시공간복잡도] (0) | 2025.01.17 |
코드트리 | HashMAP / 원소의 합이 0 {언어 : Python} (0) | 2025.01.16 |
코드트리 | HashMap / 세 수의 합 {언어 : Python} (0) | 2025.01.14 |