ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 10830번 행렬 제곱
    문제 풀이 2020. 8. 5. 19:21

    10830번 행렬제곱


    문제


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


    입력


    첫째 줄에 행렬의 크기 N과 B가 주어진다. (2 ≤ N ≤  5, 1 ≤ B ≤ 100,000,000,000)

    둘째 줄부터 N개의 줄에 행렬의 각 원소가 주어진다. 행렬의 각 원소는 1,000보다 작거나 같은 자연수 또는 0이다.


    출력


    첫째 줄부터 N개의 줄에 걸쳐 행렬 A를 B제곱한 결과를 출력한다.



    풀이)

    B의 범위가 크기 때문에 하나씩 곱해보는 A*A*A..*A 이런식으로 계산하면 시간초과가 나는 문제이다.


    지수 법칙을 생각해서 풀어야 하는 문제다.




    지수 법칙을 이용해 할정복(divide and conquer) 으로 푼다. 


    코드)


    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
    #include <stdio.h>
    #include <vector>
    using namespace std;
     
    typedef vector<vector<int>> matrix;
    int N, B;
     
    matrix A;
    matrix temp, result;
     
    matrix cal(matrix x, matrix y) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                temp[i][j] = 0;
                for (int t = 0; t < N; t++) {
                    temp[i][j] += x[i][t] * y[t][j];
                }
                temp[i][j] %= 1000;
            }
        }
        return temp;
    }
    int main() {
        scanf("%d %d"&N, &B);
     
        A.resize(N, vector<int>(N));
        temp.resize(N, vector<int>(N));
        result.resize(N, vector<int>(N));
     
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++scanf("%d"&A[i][j]);
            result[i][i] = 1//단위행렬로 초기값
        }
        while (B > 0)
        {
            if (B % 2 == 1)//지수가 홀수면 result * A 진행
            {
                result = cal(result, A);
            }
            A = cal(A, A);//행렬 A * A 진행
            B /= 2;
        }
     
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++printf("%d ", result[i][j]);
            printf("\n");
        }
     
        return 0;
    }
    cs


    '문제 풀이' 카테고리의 다른 글

    [백준] 2933번 미네랄  (0) 2020.08.07
    [백준] 11066번 파일합치기  (0) 2020.08.06
    [백준] 3197번 백조의 호수  (0) 2020.08.04
    [백준] 2942번 퍼거슨과 사과  (0) 2020.08.03
    [백준] 1202번 보석 도둑  (0) 2020.08.02

    댓글

Designed by Tistory.