본문 바로가기
알고리즘/백준

[백준/C,C++] 10830번: 행렬 제곱

by 이민훈 2021. 3. 26.

www.acmicpc.net/problem/10830

 

10830번: 행렬 제곱

크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

hackids.tistory.com/52

 

[백준/C,C++] 1629번: 곱셈

www.acmicpc.net/problem/1629 1629번: 곱셈 첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다. www.acmicpc.net A의 B제곱을 C로 나눈 나머지를 구..

hackids.tistory.com

hackids.tistory.com/55

 

[백준/C,C++] 2740번: 행렬 곱셈

www.acmicpc.net/problem/2740 2740번: 행렬 곱셈 첫째 줄에 행렬 A의 크기 N 과 M이 주어진다. 둘째 줄부터 N개의 줄에 행렬 A의 원소 M개가 순서대로 주어진다. 그 다음 줄에는 행렬 B의 크기 M과 K가 주어진

hackids.tistory.com

1629번: 곱셈, 2740번: 행렬 곱셈을 풀 수 있다면 충분히 풀 수있는 문제입니다.

 

행렬 A가 있을 때, $A^{B}$는 B가 짝수일 때, $A^{B/2} \times A^{B/2}$로 나타낼 수 있습니다.

 

홀수 일땐 $A^{B-1} \times A$로 나타낼 수 있습니다.

 

#include<iostream>

using namespace std;

const int MOD = 1000;
const int MAX = 5;

using ll = long long;
using Matrix = struct {
    int mat[MAX][MAX];
};

ll n, b;

void io(Matrix& m, char c)
{
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (c == 'i') cin >> m.mat[i][j];
            else cout << m.mat[i][j] % MOD << " ";
        }
        if (c == 'o') cout << "\n";
    }
}

Matrix operator*(const Matrix& a, const Matrix& b)
{
    Matrix tmp;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            tmp.mat[i][j] = 0;
            for (int k = 0; k < n; k++) {
                tmp.mat[i][j] += a.mat[i][k] * b.mat[k][j];
            }
            tmp.mat[i][j] %= MOD;
        }
    }
    return tmp;
}

Matrix power(const Matrix& m, ll num)
{
    if (num == 1) return m;
    if (num % 2 != 0) {
        return power(m, num - 1) * m;
    }
    Matrix half = power(m, num / 2);
    return half * half;
}

int main(void)
{
    cin >> n >> b;

    Matrix m;

    io(m, 'i');
    m = power(m, b);
    io(m, 'o');

    return 0;
}

 

함수 io는 행렬 입출력 함수입니다.

 

행렬 곱셈은 연산자 오버로딩을 통해 해결하였습니다.

 

power는 지수를 분할해 재귀호출하고 분할한 행렬을 곱해 반환합니다.

댓글