문제링크 : https://www.acmicpc.net/problem/10830
10830번: 행렬 제곱
크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;
typedef vector<vector<ll>> matrix;
ll N, B;
matrix multiply(matrix &a, matrix &b)
{
matrix temp(N, vector<ll>(N));
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
for(int k=0; k<N; k++)
{
temp[i][j] += (a[i][k] * b[k][j]);
}
temp[i][j] %= 1000;
}
}
return temp;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> B;
matrix arr(N, vector<ll>(N));
matrix result(N, vector<ll>(N));
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cin >> arr[i][j];
}
result[i][i] = 1; // 단위행렬로 초기화
}
while(B)
{
if(B%2) result = multiply(result, arr); //홀수 (한번 더 곱해줌)
arr = multiply(arr, arr); //짝수
B/=2;
}
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cout << result[i][j] << " ";
}
cout <<"\n";
}
return 0;
}
[백준 11444번] 피보나치 수 6 문제를 푸는 방법과 거의 동일하게 푸는 문제이다.
피보나치 수 6 문제에서 행렬 제곱을 계산하는 방법 (거듭 제곱) 이 사실상 이 문제를 푸는 방법이다.
그래서 크게 설명한 것은 없고 간단하게 다시 쓰면
B = 5 가정
5 = 4*1
= (2*2)*1
= (1*1)*(1*1)*1
위와 같으므로, 짝수 일때는 같은 값을 제곱해주고 홀수 일때는 해당 값을 한번만 더 곱해주면 된다.
여기서 또 실수를 했었는데, B의 범위가 매우 크므로 long long을 선언해줘야 했다.
여기서도 N이랑 같이 int로 선언했다가 여러번 틀렸다.
'백준 > 골드' 카테고리의 다른 글
[백준 14502번] 연구소 (C++) (0) | 2023.08.14 |
---|---|
[백준 15686번] 치킨 배달 (C++) (0) | 2023.08.12 |
[백준 2206번] 벽 부수고 이동하기 (C++) (0) | 2023.08.10 |
[백준 11444번] 피보나치 수 6 (C++) (0) | 2023.08.09 |
[백준 14938번] 서강그라운드 (C++) (0) | 2023.08.08 |