Java

[백준 10830] 행렬 제곱(JAVA)

iheeeee6-6 2023. 3. 12. 13:01
728x90

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

 

10830번: 행렬 제곱

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

www.acmicpc.net

 

 

이 문제를 풀기전에 아래의 두 문제를 먼저 풀으시는 것을 추천드립니다!

1. 행렬 곱셈

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

 

2740번: 행렬 곱셈

첫째 줄에 행렬 A의 크기 N 과 M이 주어진다. 둘째 줄부터 N개의 줄에 행렬 A의 원소 M개가 순서대로 주어진다. 그 다음 줄에는 행렬 B의 크기 M과 K가 주어진다. 이어서 M개의 줄에 행렬 B의 원소 K개

www.acmicpc.net

-> 풀이 

https://iheeeee6-6.tistory.com/51

 

[백준 2740] 행렬 곱셈 (JAVA)

https://www.acmicpc.net/problem/2740 2740번: 행렬 곱셈 첫째 줄에 행렬 A의 크기 N 과 M이 주어진다. 둘째 줄부터 N개의 줄에 행렬 A의 원소 M개가 순서대로 주어진다. 그 다음 줄에는 행렬 B의 크기 M과 K가

iheeeee6-6.tistory.com

 

 

2. 곱셈

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

 

1629번: 곱셈

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.

www.acmicpc.net

-> 풀이

https://iheeeee6-6.tistory.com/52

 

[백준 1629] 곱셈 (JAVA)

https://www.acmicpc.net/problem/1629 1629번: 곱셈 첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다. www.acmicpc.net Math.pow로 하면 시간초과가 발생한다.

iheeeee6-6.tistory.com

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

우선 이 문제는 분할 정복으로 해결할 수 있습니다.

행렬을 곱하면서 1000으로 나누고, 분할 정복을 적용하면 됩니다!

 

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

public class Main {
	static int[][] arr;
	static int n;
	static long b;

	public static void main(String[] args) throws NumberFormatException, 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());
		arr = new int[n][n];

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

		StringBuilder sb = new StringBuilder();
		int[][] result = pow(b);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++)
				sb.append(result[i][j]).append(" ");
			sb.append("\n");
		}
		System.out.println(sb);
	}

	static public int[][] pow(long cnt) {
		if (cnt == 1) {
			return arr;
		}
		int[][] temp = pow(cnt / 2);
		if (cnt % 2 == 1) {
			int[][] temp2 = cal(temp, arr);
			return cal(temp, temp2);
		} else {
			return cal(temp, temp);
		}
	}

	static public int[][] cal(int[][] A, int[][] B) {
		int[][] r = 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++) {
					sum += (A[i][k] * B[k][j]) % 1000;
				}
				r[i][j] = sum % 1000;
			}
		}
		return r;
	}

}