파이썬 문제풀이
[백준 파이썬] 10830 행렬 제곱
냄비짱
2023. 8. 10. 04:38
728x90
📌문제 출처
백준 단계별 문제풀이 - 분할정복
https://www.acmicpc.net/problem/10830
10830번: 행렬 제곱
크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
❓ 문제
❗ 풀이
- 분할 정복(재귀 함수) 사용
📗 풀이 코드
import sys
input = sys.stdin.readline
def mul_func(a1,a2): # 행렬 곱 연산 함수
mul = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
a1_row = a1[i]
for j in range(n):
a2_col = [a2_row[j] for a2_row in a2]
mul[i][j] = sum([num_a1*num_a2 for num_a1,num_a2 in zip(a1_row,a2_col)])%1000
return mul
def dac(a,b): # 분할 정복 함수 input = 행렬, 연산횟수
if b == 1:
for i in range(n):
for j in range(n):
a[i][j] %= 1000
return a
if not b%2: # b가 짝수라면
return dac(mul_func(a,a),b//2) # 제곱행렬끼리의 ㅠ//2번 연산을 추가 진행
else : # b가 홀수라면
return mul_func(dac(mul_func(a,a),b//2),a) # 짝수일때 연산 진행 후 마지막에 a 한번 더 곱하기
n,b = map(int,input().split())
a = [list(map(int,input().split())) for _ in range(n)]
for row in dac(a,b):
print(*row)
📗 코드 해설
- 행렬 곱 연산과 분할 정복 연산을 함수로 생성
- 제곱의 나머지는 나머지의 제곱의 나머지와 같음을 이용
- b가 짝수라면 제곱 행렬끼리의 연산을 기본 배열로 활용하여 횟수를 2로 나눈다.
- b가 홀수라면 횟수에서 1을 뺀 뒤 위를 반복하고 마지막에 기본 배열을 한번 더 곱해준다.