λ°±μ€€ 10830 파이썬

2021. 12. 26. 10:20γ†πŸ”± Algorithm/Else

 

 

10830번: ν–‰λ ¬ 제곱

크기가 N*N인 ν–‰λ ¬ Aκ°€ 주어진닀. μ΄λ•Œ, A의 Bμ œκ³±μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. μˆ˜κ°€ 맀우 컀질 수 μžˆμœΌλ‹ˆ, A^B의 각 μ›μ†Œλ₯Ό 1,000으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό 좜λ ₯ν•œλ‹€.

www.acmicpc.net

 

풀지 λͺ»ν•œ 이유

1. ν–‰λ ¬ 곱을 μ½”λ“œλ‘œ 풀어내지 λͺ»ν•¨. 

2. μž¬κ·€λ₯Ό 적절히 ν™œμš©ν•˜μ§€ λͺ»ν•¨

3. μž¬κ·€ νƒˆμΆœ 쑰건 λ§Œμ΄λΌλ„ μ•Œμ•˜λ‹€λ©΄ 풀이에 μ ‘κ·Όν•  수 μžˆμ—ˆμŒ

4. λ§ˆμ§€λ§‰ 쑰건 (1000 μ΄ν•˜) 에 적절히 λŒ€μ²˜ν•˜μ§€ λͺ»ν•¨.

 


풀이 

이 문제의 핡심은 DP 라고 ν•˜λŠ”λ°, 사싀 ν–‰λ ¬μ˜ κ³±μ…ˆμ„ μ½”λ“œλ‘œ ν’€μ–΄λ‚΄λŠ” 것 μ—­μ‹œ 핡심이라고 μƒκ°ν•œλ‹€.

ν–‰λ ¬μ˜ κ³±μ…ˆμ€ μ΄λŸ°μ‹μœΌλ‘œ μ§„ν–‰λœλ‹€. (1, 3) x (3, 1) 처럼 μ•ž ν–‰λ ¬μ˜ λ‘λ²ˆμ§Έ μ’Œν‘œ(3) 와 λ’· ν–‰λ ¬μ˜ 첫번째 μ’Œν‘œ(3) κ°€ κ°™μ•„μ•Ό ν–‰λ ¬μ˜ 곱이 이루어진닀. 10λ…„μ „ 쀑학ꡐ μˆ˜ν•™κ³Όμ •μ—μ„œ 배운 기얡이 λ‚œλ‹€.

이λ₯Ό μ½”λ“œλ‘œ ν’€μ–΄λ‚Ό λ•Œλ„ 이 원리λ₯Ό μ μš©ν•˜λŠ”κ²Œ μ€‘μš”ν•˜λ‹€.

def matrix_mul(mat_a, mat_b):
    length = len(mat_a)
    temp = [[0] * length for _ in range(length)]
    for i in range(length):
        for j in range(length):
            for k in range(length):
                temp[i][j] += mat_a[i][k] * mat_b[k][j]
    return temp

μ—¬κΈ°μ„œ temp λΌλŠ” μ›μ†Œκ°€ λͺ¨λ‘ 0인 μž„μ‹œ 배열을 μƒμ„±ν•œλ‹€. temp λŠ” 각 ν–‰λ ¬μ˜ κ³±μ…ˆμ˜ κ²°κ³Όλ₯Ό λ¦¬ν„΄ν•˜κ³ , 맀번 matrix_mul() 이 호좜될 λ•Œλ§ˆλ‹€ μ΄ˆκΈ°ν™” λœλ‹€. 즉 동일 ν–‰λ ¬μ˜ μ œκ³±μ„ temp λΌλŠ” μ΄λ¦„μœΌλ‘œ λ¦¬ν„΄ν•˜λŠ” 것이닀.

 

 

 

 

μ½”λ“œ

import sys


def matrix_mul(mat_a, mat_b):
    length = len(mat_a)
    temp = [[0] * length for _ in range(length)]
    for i in range(length):
        for j in range(length):
            for k in range(length):
                temp[i][j] += mat_a[i][k] * mat_b[k][j]
            temp[i][j] %= 1000
    return temp


def matrix_pow(original, n):
    if n == 1:
        return original
    if n % 2 == 0:
        temp = matrix_pow(original, n // 2)
        return matrix_mul(temp, temp)
    else:
        temp = matrix_pow(original, n - 1)
        return matrix_mul(temp, original)


read = sys.stdin.readline
N, M = map(int, read().split())
matrix = [list(map(int, read().split())) for _ in range(N)]
result = matrix_pow(matrix, M)
for row in result:
    for num in row:
        print(num % 1000, end=' ')
    print()