백준 알고리즘 10830번 : 행렬 제곱

링크

https://www.acmicpc.net/problem/10830

문제

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

입력

첫째 줄에 행렬의 크기 N과 B가 주어진다. (2 ≤ N ≤ 5, 1 ≤ B ≤ 100,000,000,000)

둘째 줄부터 N개의 줄에 행렬의 각 원소가 주어진다. 행렬의 각 원소는 1,000보다 작거나 같은 자연수 또는 0이다.

출력

첫째 줄부터 N개의 줄에 걸쳐 행렬 A를 B제곱한 결과를 출력한다.

예제 입력 및 출력

풀이법

행렬....을 계산할 때 한 것을 그대로 코드로 구현해주면 되지만 구현력이 딸려서 참고해가면서 풀었다.

풀이 코드(C++)

#include <iostream>
#include <vector>
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
#define ll long long
typedef vector<vector<ll>> matrix;
const long long mod = 1000;

matrix operator*(const matrix &a, const matrix &b)
{
    ll size = a.size();
    matrix res(size, vector<ll>(size));
    for (ll i = 0; i < size; i++)
    {
        for (ll j = 0; j < size; j++)
        {
            for (ll k = 0; k < size; k++)
            {
                res[i][j] += a[i][k] * b[k][j];
            }
            res[i][j] %= mod;
        }
    }
    return res;
}

// 행렬 a를 n제곱
matrix power(matrix a, ll n)
{
    ll size = a.size();
    matrix res(size, vector<ll>(size));
    for (ll i = 0; i < size; i++)
    {
        res[i][i] = 1; // 단위행렬
    }
    while (n > 0)
    {
        // n이 홀수이면
        if (n % 2 == 1)
        {
            res = res * a;
        }
        n /= 2;
        a = a * a;
    }
    return res;
}

void PrintMatrix(const matrix &a)
{
    ll size = a.size();
    for (ll i = 0; i < size; i++)
    {
        for (ll j = 0; j < size; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << "\n";
    }
}

int main()
{
    fastio;
    ll a, b;
    cin >> a >> b;
    matrix input(a, vector<ll>(a));
    for (ll i = 0; i < a; i++)
    {
        for (ll j = 0; j < a; j++)
        {
            cin >> input[i][j];
        }
    }
    PrintMatrix(power(input, b));
    return 0;
}
참고 블로그

https://seokjin2.tistory.com/9?category=759919
(소스 참고)

좋은 웹페이지 즐겨찾기