본문 바로가기
Algorithm/📖Baekjoon

#10830 행렬 제곱

by yewoneeee 2022. 4. 9.

# 문제

# 입력/출력

 

# 풀이

내가 작성한 코드는 아래와 같음

#include <iostream>
using namespace std;
const int mod = 1000;
int mat[5][5];
int result[5][5];
int fin[5][5];

void cal(int N) {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			int temp = 0;
			for (int k = 0; k < N; k++) {
				temp += result[i][k] * mat[k][j];
			}
			fin[i][j] = temp % mod;
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			result[i][j] = fin[i][j];
		}
	}
}

int main() {
	int N;
	long long B;
	cin >> N >> B;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cin >> mat[i][j];
			result[i][j] = mat[i][j];
		}
	}
	for (int i = 0; i < B-1; i++) {
		cal(N);
	} 
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cout << result[i][j] << " ";
		}
		cout << "\n";
	}
}

이렇게 코드를 작성하니 시간 초과가 뜸

그래서 구글링해봤더니

이 부분에서 시간 초과가 나는 것 같다

아무래도 B의 범위가 1 ≤ B ≤ 100,000,000,000 다 보니 시간 초과가 뜨는 것 같음

그래서 찾아보니

위와 같은 알고리즘을 찾았다

 

위의 글만 읽고는 이해가 힘들어서 빠른 거듭제곱 알고리즘을 다시 찾아봤다

https://namnamseo.tistory.com/entry/%EB%B9%A0%EB%A5%B8-%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1

 

빠른 거듭제곱

거듭제곱 a의 b승을 c로 나눈 나머지를 구해야 할 때가 있습니다. 참고로 거듭제곱을 영어로는 power라고 합니다. 일단 단순히 구현하면 이렇게 할 수 있습니다. // integer power function int ipow(int a, int

namnamseo.tistory.com

위의 알고리즘을 참고해서 아래 코드 작성

 

코드는 아래 블로그 참고

https://seokjin2.tistory.com/9

 

[백준 10830번] 행렬 제곱 - (빠른 거듭제곱 알고리즘)

문제 링크: https://www.acmicpc.net/problem/10830 10830번: 행렬 제곱 크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으..

seokjin2.tistory.com

#include <iostream>
using namespace std;
long long N, B;
long long mat[5][5]; // 입력받은 행렬 값 저장
long long res[5][5]; // 결과값 저장 행렬
long long temp[5][5]; // 중간 계산 값 저장 행렬

void mul_mat(long long x[5][5], long long y[5][5]) {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			temp[i][j] = 0;
			for (int k = 0; k < N; k++) {
				temp[i][j] += x[i][k] * y[k][j]; // 행렬 곱 계산
			}
			temp[i][j] %= 1000; // 1000으로 나눈 나머지 저장
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			x[i][j] = temp[i][j];
		}
	}
}

int main(){
	cin >> N >> B;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cin >> mat[i][j];
			res[i][i] = 1; // 단위행렬로 초기화
		}
	}
	while (B != 0) { 
		if (B % 2 == 1) { // 제곱해야 하는 수가 홀수면
			mul_mat(res, mat); // {mat^(2n)}*mat -> 2n은 따로 계산하고 mat만 일단 결과 행렬에 곱셈 진행
		}
		mul_mat(mat, mat); // 2n은 n번 계산해서 제곱(^2)해주면 되기 때문에
		B /= 2; // n번만 계산하기 위해? 행렬은 곱셈 진행하고 2를 계속해서 나눠줌
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cout << res[i][j] << " ";
		}
		cout << "\n";
	}
}

성공ㅋㅋ

'Algorithm > 📖Baekjoon' 카테고리의 다른 글

#2839 설탕 배달  (0) 2022.04.11
#7579 앱  (0) 2022.04.10
#2749 피보나치 수 3  (0) 2022.04.08
#9471 피사노 주기  (0) 2022.04.08
#1655 가운데를 말해요  (0) 2022.04.05

댓글