[BOJ] #10830 ํ–‰๋ ฌ ์ œ๊ณฑ (Python, ๋ถ„ํ• ์ •๋ณต)

๋ฐ˜์‘ํ˜•

 

 

๐ŸŒฑ ๋ฌธ์ œ

 

 

๐ŸŒฑ ํ’€์ด

์ด ๋ฌธ์ œ์˜ ๊ด€๊ฑด์€ 100,000,000,000๊นŒ์ง€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ํฐ ์ง€์ˆ˜๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ–‰๋ ฌ์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ณฑํ•˜๋Š” ๋Œ€์‹ , ํ–‰๋ ฌ์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ์„ ๋ถ„ํ•  ์ •๋ณต(Divide and Conquer) ๊ธฐ๋ฒ•์œผ๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

 

1) ์ž…๋ ฅ ๋ฐ›๊ธฐ


  
N, B = map(int, input().split())
matrix = []
for _ in range(N):
matrix.append(list(map(int, input().split())))

 

2) ํ–‰๋ ฌ ์ œ๊ณฑ์„ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜(Divide and Conquer)


  
def pow_matrix(matrix, B):
"""
ํ–‰๋ ฌ matrix๋ฅผ B ์ œ๊ณฑํ•˜๋Š” ํ•จ์ˆ˜
"""
if B == 1:
return [[element % 1000 for element in row] for row in matrix]
if B == 2:
return multiply_matrix(matrix, matrix)
if B % 2 == 0:
matrix = pow_matrix(pow_matrix(matrix, B//2), 2)
else:
matrix = multiply_matrix(pow_matrix(
pow_matrix(matrix, B//2), 2), matrix)
return matrix

์ง€์ˆ˜๊ฐ€ ๋งค์šฐ ํฌ๊ธฐ ๋•Œ๋ฌธ์— ํ–‰๋ ฌ์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ณฑํ•˜๋ฉด ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋ถ„ํ•  ์ •๋ณต ๊ธฐ๋ฒ•์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ˆ˜์‹์œผ๋กœ ํšจ์œจ์ ์œผ๋กœ ๊ณ„์‚ฐ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

โ€ข  B๊ฐ€ ์ง์ˆ˜์ผ ๊ฒฝ์šฐ:  AB=AB/2ร—AB/2

โ€ข  B๊ฐ€ ํ™€์ˆ˜์ผ ๊ฒฝ์šฐ:  AB=Aร—ABโˆ’1=Aร—A(Bโˆ’1)/2ร—A(Bโˆ’1)/2

B๊ฐ€ ์ง์ˆ˜์ผ ๋•Œ์™€ ํ™€์ˆ˜์ธ ๊ฒฝ์šฐ ๊ฐ๊ฐ์˜ ์ˆ˜์‹์œผ๋กœ ์žฌ๊ท€์ ์œผ๋กœ ๋“ค์–ด๊ฐ€๋„๋ก ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์žฌ๊ท€ํ•จ์ˆ˜์˜ base case๊ฐ€ ๋˜๋Š” ์กฐ๊ฑด์€ B๊ฐ€ 1์ผ ๋•Œ์™ธ 2์ผ ๋•Œ์ž…๋‹ˆ๋‹ค. B๊ฐ€ 2์ผ ๋•Œ๋Š” ํ–‰๋ ฌ์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ์„ ๊ณ„์‚ฐ(multiply_matrix() ํ•จ์ˆ˜)ํ•˜์—ฌ ๋ฆฌํ„ดํ•˜๊ณ , B๊ฐ€ 1์ผ ๋•Œ๋Š” ๋ชจ๋“  ์›์†Œ๋ฅผ 1000์œผ๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€๋กœ ๋ฐ”๊พธ์–ด ๊ทธ๋Œ€๋กœ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค!

 

3) ๋‘ ํ–‰๋ ฌ์„ ๊ณฑํ•˜๋Š” ํ•จ์ˆ˜


  
def multiply_matrix(A, B):
"""
๋‘ ํ–‰๋ ฌ A, B๋ฅผ ๊ณฑํ•˜๋Š” ํ•จ์ˆ˜
"""
n = len(A)
result = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
result[i][j] = sum(
[(a * b) for a, b in zip(A[i], [b[j] for b in B])]) % 1000
return result

 

ํ–‰๋ ฌ์„ ๊ฑฐ๋“ญ์ œ๊ณฑํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋Š” pow_matrix() ํ•จ์ˆ˜์•ˆ์—์„œ ํ˜ธ์ถœ๋˜๋Š”๋ฐ, B=2์ธ ๊ธฐ์ € ์กฐ๊ฑด์— ๊ฑธ๋ฆด ๋•Œ์™€ B๊ฐ€ ํ™€์ˆ˜์ธ ๊ฒฝ์šฐ, Aร—ABโˆ’1๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

4) ์ถœ๋ ฅํ•˜๊ธฐ


  
for row in result:
print(' '.join(map(str, row)))

 

๐ŸŒฑ ์ •๋‹ต ์ฝ”๋“œ


  
# !/usr/bin/python
# -*- coding: utf-8 -*-
# boj 10830 ํ–‰๋ ฌ์ œ๊ณฑ
import sys
input = sys.stdin.readline
def multiply_matrix(A, B):
n = len(A)
result = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
result[i][j] = sum(
[(a * b) for a, b in zip(A[i], [b[j] for b in B])]) % 1000
return result
def pow_matrix(matrix, B):
if B == 1:
return [[element % 1000 for element in row] for row in matrix]
if B == 2:
return multiply_matrix(matrix, matrix)
if B % 2 == 0:
matrix = pow_matrix(pow_matrix(matrix, B//2), 2)
else:
matrix = multiply_matrix(pow_matrix(
pow_matrix(matrix, B//2), 2), matrix)
return matrix
N, B = map(int, input().split())
matrix = []
for _ in range(N):
matrix.append(list(map(int, input().split())))
result = pow_matrix(matrix, B)
for row in result:
print(' '.join(map(str, row)))
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€