와챠의 우당탕탕 개발 기록장
[백준]행렬제곱/10830 풀이 JAVA 본문
반응형
문제
크기가 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제곱한 결과를 출력한다.
풀이(JAVA)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
import java.util.*; | |
public class Main { | |
final static int MOD = 1000; | |
static int N; | |
static int[][] A; | |
public static void main(String[] args) throws IOException { | |
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | |
// N, B 입력 | |
StringTokenizer st = new StringTokenizer(br.readLine()); | |
N = Integer.parseInt(st.nextToken()); | |
long B = Long.parseLong(st.nextToken()); | |
// 배열 A 생성 | |
A = new int[N][N]; | |
// 배열 A 채우기 | |
// B=1일 때, pow에서 A 그대로 반환되기 때문에 미리 1000 나눠주기 | |
for (int i = 0; i < N; i++) { | |
st = new StringTokenizer(br.readLine()); | |
for (int j = 0; j < N; j++) | |
A[i][j] = Integer.parseInt(st.nextToken()) % MOD; | |
} | |
int[][] result = pow(A, B); | |
// 출력 | |
StringBuilder sb = new StringBuilder(); | |
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 int[][] pow(int[][] base, long exponent) { | |
// 지수가 1이면 그냥 그대로... | |
if (exponent == 1L) return base; | |
// 지수의 절반 구하기 | |
int[][] half = pow(base, exponent / 2); | |
// 행렬 제곱하기 | |
half = mul(half, half); | |
// 현재 지수가 홀수면 A 한 번 더 곱해주기 | |
if (exponent % 2 == 1L) half = mul(half, A); | |
return half; | |
} | |
// 행렬 곱하기 | |
static int[][] mul(int[][] o1, int[][] o2) { | |
int[][] result = new int[N][N]; | |
for (int i = 0; i < N; i++) | |
for (int j = 0; j < N; j++) | |
for (int k = 0; k < N; k++) { | |
result[i][j] += o1[i][k] * o2[k][j]; | |
result[i][j] %= MOD; | |
} | |
return result; | |
} | |
} |

......헷갈려
.................어려워
행렬은 처음 다뤄보는 거 같은데 쉬운 거 같으면서도 헷갈림
낼 더 공부해야 함
반응형
'코딩 일기장 > CodingTest' 카테고리의 다른 글
[백준]탈옥/9376 풀이 JAVA (0) | 2021.08.09 |
---|---|
[백준]피보나치 수 3/2749 풀이 JAVA (0) | 2021.08.04 |
[백준]이항 계수3/11041 풀이 JAVA (0) | 2021.07.04 |
[백준]백조의 호수/3197 풀이 JAVA (0) | 2021.07.03 |
[백준]가운데를 말해요/1655 풀이 JAVA (0) | 2021.07.02 |