nukw0n
찐이의 개발 연결구과
nukw0n
전체 방문자
오늘
어제
  • 분류 전체보기 (38)
    • 유연해지기 (21)
      • React.js (11)
      • Javascript (5)
      • webpack & babel (1)
      • etc. (4)
      • Next.js (0)
    • 단단해지기 (13)
      • Algorithm (9)
      • Computer Science (4)
    • 속닥속닥 (4)
    • 책읽는 남자 (0)

블로그 메뉴

    공지사항

    인기 글

    태그

    • useBuiltIns
    • bfs
    • 알고리즘
    • history API
    • React
    • javascript
    • intersectionobserver api
    • vanilla spa
    • sass vs postcss
    • React 18
    • Batching
    • 프로그래머스
    • Auto Batching
    • error 안 뜸
    • fallback UI
    • 콜백 ref
    • 백준
    • dfs
    • Error Boundary
    • vallia 라우터

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    nukw0n

    찐이의 개발 연결구과

    [백준/BOJ 알고리즘] 10830 행렬 제곱 C++
    단단해지기/Algorithm

    [백준/BOJ 알고리즘] 10830 행렬 제곱 C++

    2021. 9. 12. 15:15

     

    https://www.acmicpc.net/problem/10830

     

    10830번: 행렬 제곱

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

    www.acmicpc.net

     

    주어진 행렬 A에 대하여 입력 B만큼 제곱한 행렬을 출력하는 문제이다.

    B는 100,000,000,000 이하의 값을 갖는다. 즉, A를 B번 제곱하는 방식으로는 해결할 수 없다.

    분할정복 을 통해 문제를 해결할 수 있다.

    A의 거듭제곱은 다음과 같이 나타낼 수 있다.

     

     

     


    분할정복을 통해 100,000,000,000번 제곱한 값을 찾는다면,

    약 36~7번의 연산으로 찾을 수 있다.

    최종적으로 시간복잡도는 다음과 같다.

    O(logB * N^3)


    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <utility>
    #define MAX_N 5
    #define lli long long int
    using namespace std;
    using vvi = vector<vector<int> >;
    int n;
    lli bb;
    vvi A(MAX_N, vector<int>(MAX_N, 0));
    vvi squaredA;
    
    vvi matMultiply(vvi a, vvi b) {
      vvi res(MAX_N,vector <int>(MAX_N,0));
      int sum;
      for (int r = 0; r < n; r++) {
            for (int c = 0; c < n; c++) {
                sum = 0;
                for (int k = 0; k < n; k++) {
                    sum += ((a[r][k] % 1000) * (b[k][c] % 1000)) %1000;
                }
                res[r][c] = sum % 1000;
            }
        }
    
      return res;
    }
    
    vvi solution(lli now) {
      if (now == 1) return A;
      if (now == 2) return squaredA;
    
      vvi devidedA = solution(now/2);
      vvi squaredDevidedA = matMultiply(devidedA, devidedA);
    
      if (now % 2) return matMultiply(squaredDevidedA, A);
      else return squaredDevidedA;
    }
    
    int main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cin >> n >> bb;
      for (int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
          cin >> A[i][j];
        }
      }
      squaredA = matMultiply(A, A);
      vvi res = solution(bb);
    
      for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
          cout << res[i][j] % 1000 << " ";
        }
        cout << "\n";
      }
    }

    '단단해지기 > Algorithm' 카테고리의 다른 글

    [프로그래머스] 모음사전 Javascript  (0) 2021.09.18
    [백준/BOJ 알고리즘] 17845 수강 과목 C++  (0) 2021.09.12
    [백준/BOJ 알고리즘] 16236 아기상어 C++  (0) 2020.09.17
    [백준/BOJ 알고리즘] 1039 교환 C++  (1) 2020.09.10
    [백준/BOJ 알고리즘] 2573 빙산 C++  (1) 2020.09.07
      '단단해지기/Algorithm' 카테고리의 다른 글
      • [프로그래머스] 모음사전 Javascript
      • [백준/BOJ 알고리즘] 17845 수강 과목 C++
      • [백준/BOJ 알고리즘] 16236 아기상어 C++
      • [백준/BOJ 알고리즘] 1039 교환 C++
      nukw0n
      nukw0n
      프론트엔드 개발자 권혁진입니다.

      티스토리툴바