어흥

[백준 10830] 행렬제곱 (C++) 본문

알고리즘/백준

[백준 10830] 행렬제곱 (C++)

라이언납시오 2020. 3. 4. 14:58
728x90
반응형

문제 링크: https://www.acmicpc.net/problem/10830

 

10830번: 행렬 제곱

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

www.acmicpc.net

1. 주의할 점

- B가 최대 1000억까지 증가할 수 있다(단순 연산만 해도 100초)

- 시간 제한: 1초

- 행렬의 원소는 매 계산마다 MOD 1000 한 결과를 보유한다

 

2. 해결법

- B를 logB만큼 줄여서 1초내에 연산을 끝내도록 한다

 

3. 함수 기능

- mul 함수: 2차행렬 X 2차행렬을 위한 함수

- pow 함수: v^B 의 결과를 돌려준다

#define MOD 1000
#include <iostream>
#include <vector>
using namespace std;
int num;
vector<vector<int>> mul(vector<vector<int>> &a, vector<vector<int>> &b) {
	vector<vector<int>> result(num, vector<int>(num, 0));
	for (int i = 0; i < num; i++) {
		for (int j = 0; j < num; j++) {
			for (int k = 0; k < num; k++) {
				result[i][j] += (a[i][k] * b[k][j]);
				result[i][j] %= MOD;
			}
		}
	}
	return result;
}

vector<vector<int>> pow(vector<vector<int>> &a, vector<vector<int>> &v, long long square) {
	if (square == 1) return v;
	vector<vector<int>> temp(num, vector<int>(num, 0));
	if (square % 2 == 0) {
		temp = pow(a, v, square / 2);
		return mul(temp, temp);
	}
	temp = pow(a, v, square - 1);
	return mul(temp, a);
}

int main() {
	long long square;
	cin >> num >> square;
	vector<vector<int>> v(num, vector<int>(num, 0));
	vector<vector<int>> arr(num, vector<int>(num, 0));
	for (int i = 0; i < num; i++)
		for (int j = 0; j < num; j++) {
			cin >> arr[i][j];
			v[i][j] = arr[i][j];
		}
	v = pow(arr,v,square);
	for (int i = 0; i < num; i++) {
		for (int j = 0; j < num; j++)
			cout << v[i][j]%MOD<<" ";
		cout << endl;
	}
	system("pause");
	return 0;
}

 

728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 12100] 2048 (Easy) (C++)  (0) 2020.03.05
[백준 14500] 테트로미노 (C++)  (0) 2020.03.05
[백준 16953] A → B (C++)  (0) 2020.03.04
[백준 2056] 작업 (C++)  (0) 2020.03.04
[백준 2186] 문자판 (C++)  (0) 2020.03.04
Comments