반응형
https://www.acmicpc.net/problem/10830
10830번: 행렬 제곱
크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
[ 문제풀이 ]
일반적인 분할 정복 문제와 똑같이 풀면 됩니다!
제곱수 n이 짝수일 때 $A^{\frac{n}{2}}\times A^{\frac{n}{2}}$ 홀수일 때 $A^{n-1}\times A$의 방식으로 계산해나가면 O(logn)의 시간 복잡도로 풀 수 있습니다.
[ 소스 코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include<iostream> #include<vector> #define ll long long using namespace std; int N; ll B; vector<vector<int>> A; //행렬 A vector<vector<int>> ans; //정답 행렬 vector<vector<int>> gop(vector<vector<int>> a, vector<vector<int>> b) //행렬 곱 { vector<vector<int>> ret; ret.resize(N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int sum = 0; for (int k = 0; k < N; k++) { sum += (a[i][k] * b[k][j]) % 1000; sum %= 1000; } ret[i].push_back(sum); } } return ret; } vector<vector<int>> conquer(ll num) //분할 정복 { if (num == 1) { return A; } if (num % 2 == 0) { vector<vector<int>> temp = conquer(num / 2); return gop(temp, temp); } else { return gop(conquer(num - 1), conquer(1)); } } int main() { cin >> N >> B; A.resize(N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int num; cin >> num; A[i].push_back(num); } } ans = conquer(B); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { cout << ans[i][j] % 1000 << " "; } cout << endl; } } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 2150번 - Strongly Connected Component (C++) (0) | 2022.07.24 |
---|---|
[ 백준 ] 1948번 - 임계경로 (C++) (0) | 2022.07.22 |
[ 백준 ] 1786번 - 찾기 (C++) (0) | 2022.07.20 |
[ 백준 ] 1761번 - 정점들의 거리 (C++) (0) | 2022.07.18 |
[ 백준 ] 1708번 - 볼록 껍질 (C++) (0) | 2022.07.17 |