베오
DCode
베오
전체 방문자
오늘
어제
  • 분류 전체보기 (218)
    • 공지사항 (1)
    • 잡설 (1)
    • Programming (33)
      • [C] (1)
      • [Java] (4)
      • [Python] (2)
      • [Android] (2)
      • [Network] (0)
      • [Operation System] (2)
      • [Spring Boot] (22)
      • [Docker] (0)
    • Algorithm (31)
      • 자료구조 (2)
      • 알고리즘 (Java) (14)
      • 알고리즘 (기초) (15)
    • Coding Test (131)
      • BOJ (131)
      • Algospat (0)
    • 이론적인거 (14)
      • 보안 (5)
      • 오류 해결 (2)
      • 디자인 패턴 (5)
      • 네트워크 (1)
      • 기타 (1)
    • 최신기술 (4)
      • 블록체인 (1)
    • [Project] (1)

블로그 메뉴

  • 🐈‍⬛ GitHub
  • 📫 방명록
  • 🔖 태그

공지사항

인기 글

티스토리

hELLO · Designed By 정상우.
베오

DCode

Coding Test/BOJ

[BOJ/JAVA] 10830번: 행렬 제곱

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

키워드

  • 크기가 N*N인 행렬 A가 주어진다.
  • A의 B제곱을 구하는 프로그램

구현

  • matrixMultiply
    • 두 정방행렬의 곱을 구하는 메소드
    • 시간복잡도
      • O(N^3)
    • 정방행렬의 곱은 다음과 같다.
      [a1a2a3a4]∗[b1b2b3b4]=[a1b1+a2b3a1b2+a2b4a3b1+a4b3a3b2+a4b4]\begin{bmatrix} a_1 & a_2 \\ a_3 & a_4 \end{bmatrix} * \begin{bmatrix} b_1 & b_2 \\ b_3 & b_4 \end{bmatrix} = \begin{bmatrix} a_1b_1+a_2b_3 & a_1b_2+a_2b_4 \\ a_3b_1+a_4b_3 & a_3b_2+a_4b_4 \end{bmatrix}[a1​a3​​a2​a4​​]∗[b1​b3​​b2​b4​​]=[a1​b1​+a2​b3​a3​b1​+a4​b3​​a1​b2​+a2​b4​a3​b2​+a4​b4​​]
  • calcMatrix
    • 분할정복을 이용한 행렬을 제곱하는 메소드
    • 제곱수를 절반으로 줄여가며 계산을 진행한다.
      ab=ab2∗ab2(n이 짝수)ab=ab2∗ab2∗a1(n이 홀수)\begin{aligned} a^b &= a^{b\over 2}*a^{b\over2} \qquad(n이\,짝수)\\ a^b &= a^{b\over 2}*a^{b\over2}*a^1\qquad(n이\,홀수)\\ \end{aligned}abab​=a2b​∗a2b​(n이짝수)=a2b​∗a2b​∗a1(n이홀수)​
    • 제곱수가 2라면 matrixMultiply 메소드를 호출하여 제곱 계산을 한다.
    • 제곱수가 1이라면 matrix를 반환한다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class java_10830 {
    static int N;
    static long B;

    static int original[][];

    final static int MOD = 1000;

    static int[][] matrixMultiply(int matrixA[][], int matrixB[][]) {
        int nextMatrix[][] = new int[N][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++) {
                    int tmp = (matrixA[i][k] * matrixB[k][j]) % MOD;
                    sum += tmp;
                }

                nextMatrix[i][j] = sum % MOD;
            }
        }

        return nextMatrix;
    }

    static void printResult(int result[][]) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(result[i][j] % MOD + " ");
            }
            System.out.println();
        }
    }

    // 분할정복을 이용한 행렬제곱
    static int[][] calcMatrix(int matrix[][], long exp) {
        // 1은 그냥 반환
        if (exp == 1) {
            return matrix;
        }

        // 2는 그냥 제곱하기
        if (exp == 2) {
            return matrixMultiply(matrix, matrix);
        }

        int resultMatrix[][] = calcMatrix(matrix, exp / 2);
        resultMatrix = matrixMultiply(resultMatrix, resultMatrix);

        if (exp % 2 != 0) {
            resultMatrix = matrixMultiply(resultMatrix, original);
        }

        return resultMatrix;
    }

    static void solution() {
        int result[][] = calcMatrix(original, B);

        printResult(result);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        B = Long.parseLong(st.nextToken());

        original = new int[N][N];

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                original[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 제곱하는 메소드
        solution();

        br.close();
    }
}


Uploaded by N2T

'Coding Test > BOJ' 카테고리의 다른 글

[BOJ/JAVA] 1612번: 가지고 노는 1  (0) 2023.02.07
[BOJ/JAVA] 1644번: 소수의 연속합  (0) 2023.02.07
[BOJ/JAVA] 2960번: 에라토스테네스의 체  (0) 2023.02.07
[BOJ/JAVA] 1822번: 차집합  (0) 2023.01.30
[BOJ/JAVA] 2110번: 공유기 설치  (0) 2023.01.30
    'Coding Test/BOJ' 카테고리의 다른 글
    • [BOJ/JAVA] 1612번: 가지고 노는 1
    • [BOJ/JAVA] 1644번: 소수의 연속합
    • [BOJ/JAVA] 2960번: 에라토스테네스의 체
    • [BOJ/JAVA] 1822번: 차집합
    베오
    베오

    티스토리툴바