문제
https://www.acmicpc.net/problem/10830
10830번: 행렬 제곱
크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
풀이 과정
분할 정복 알고리즘을 적용한다. 행렬 곱 함수를 작성한 뒤, 행렬의 제곱을 기록하며 결과를 이용하도록 구현한다.
예를 들어 A^9를 구한다고 가정했을 때, A^9 = A * (A^4) * (A^4) 형태로 곱이 이루어지며, O(logN)의 시간 복잡도를 가진다.
정답 배열을 초기화할 때는 곱을 해도 원래 형태가 나오도록 단위행렬 형태로 초기화해야 한다.
소스 코드
#include <iostream>
#include <cstring>
using namespace std;
long long N,B;
long long A[5][5];
long long ans[5][5];
void mat_mul(long long a[5][5], long long b[5][5]){
long long temp[5][5];
memset(temp, 0, sizeof(temp));
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] = temp[i][j] % 1000;
}
}
memcpy(a,temp,sizeof(temp));
}
int main(){
cin >> N >> B;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cin >> A[i][j];
}
ans[i][i]=1;
}
while(B>0){
if(B%2==1){
mat_mul(ans,A);
}
mat_mul(A,A);
B /= 2;
}
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cout << ans[i][j] << " ";
}
cout << "\n";
}
return 0;
}
결과 및 후기
'코딩테스트 준비 > BOJ (Baekjoon Online Judge)' 카테고리의 다른 글
[백준 11066][C++] 파일 합치기 (0) | 2022.08.11 |
---|---|
[백준 2749][C++] 피보나치 수 3 (0) | 2022.08.10 |
[백준 11401][C++] 이항 계수 3 (0) | 2022.08.08 |
[백준 12865][C++] 평범한 배낭 (0) | 2022.08.06 |
[백준 23291][C++] 어항 정리 (0) | 2022.08.05 |