티스토리 뷰

Algorithm/BaekJoon

[BOJ] 10830. 행렬 제곱

cherishee 2020. 3. 1. 11:25

문제

크기가 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제곱한 결과를 출력한다.

예제 입력

2 5

1 2

3 4

예제 출력 

69 558

337 406

예제 입력 

3 3

1 2 3

4 5 6

7 8 9

예제 출력 

468 576 684

62 305 548

656 34 412

예제 입력

5 10

1 0 0 0 1

1 0 0 0 1

1 0 0 0 1

1 0 0 0 1

1 0 0 0 1

예제 출력 

512 0 0 0 512

512 0 0 0 512

512 0 0 0 512

512 0 0 0 512

512 0 0 0 512


풀이

앞에서 풀었던 거듭제곱 문제의 풀이와 거의 동일하다. (단지 행렬일 뿐)

계속 틀렸던 이유는...문제에서 주이진 범위를 제대로 보지 않았다. b의 타입을 long으로 해야했었고 출력할 때도 % 1000을 해줘야한다..

항상 주어지는 조건을 잘 보자!!!

코드

import java.util.Scanner;

public class B10830 {
    static int n;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        long b = sc.nextLong();
        long[][] data = new long[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                data[i][j] = sc.nextLong();
            }
        }
        long[][] result = pow(data, b);
        printData(result);
    }

    static long[][] pow(long[][] data, long b) {

        if (b == 0) {
            long[][] tmp = new long[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    tmp[i][j] = 1;
                }
            }
            return tmp;
        }
        if (b == 1)
            return data;
        if (b % 2 == 1) {
            //홀수
            long[][] tmp = pow(data, b - 1);
            return countPow(data, tmp);
        } else {
            //짝수
            long[][] tmp = pow(data, b / 2);
            return countPow(tmp, tmp);
        }
    }

    static long[][] countPow(long[][] dataA, long[][] dataB) {
        long[][] result = new long[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                long tmp = 0;
                for (int k = 0; k < n; k++) {
                    tmp += dataA[i][k] * dataB[k][j];
                }
                result[i][j] = tmp % 1000;
            }
        }
        return result;
    }

    static void printData(long[][] result) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print((result[i][j]%1000)  + " ");
            }
            System.out.println("");
        }
    }
}

문제 출처 : https://www.acmicpc.net/problem/10830

'Algorithm > BaekJoon' 카테고리의 다른 글

[BOJ] 10799.쇠막대기  (0) 2020.08.12
[BOJ] 1181. 단어정렬  (0) 2020.08.06
[BOJ] K번째 수  (0) 2020.03.08
[BOJ] 11401. 이항 계수 3  (1) 2020.03.01
[BOJ]1629. 곱셈  (0) 2020.02.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
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
글 보관함