sm 기술 블로그
167. 1629(곱셈) - 자바 본문
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long A = sc.nextLong();
long B = sc.nextLong();
long C = sc.nextLong();
System.out.println(power(A, B, C));
}
private static long power(long A, long B, long C) {
if (B == 0) {
return 1;
}
long tmp = power(A, B / 2, C);
if (B % 2 == 1) {
return (tmp * tmp % C) * A % C;
} else {
return (tmp * tmp) % C;
}
}
}
문제요약
A,B,C가 주어지는데 A를 B번 곱한 값을 C로 나누어라 (A,B,C <= 2,147,483,647)
설명
수가 매우매우 크기 때문에 온전히 A를 B번 곱하면 시간초과가 발생할 수 밖에 없다.
따라서 분할정복을 사용하면 된다.
제곱에는 특징이 있다.
다음과 같이 11승을 단 3번만으로 연산을 끝낼 수 있다. O(log N)
단, 두가지 경우를 생각해야한다.
1. 지수가 짝수일 때
예를 들어 2^10인 경우 2^5 * 2^5로 나타낼 수 있다.
N^(k/2) * N^(k/2)
2. 지수가 홀수일 때
예를 들어 2^11인 경우 2^5 * 2^5 * 2 로 나타낼 수 있다.
N^((k-1)/2) * N^((k-1)/2) * N
long A = sc.nextLong();
long B = sc.nextLong();
long C = sc.nextLong();
먼저 A,B,C를 받는다.
private static long power(long A, long B, long C) {
if (B == 0) {
return 1;
}
long tmp = power(A, B / 2, C);
if (B % 2 == 1) {
return (tmp * tmp % C) * A % C;
} else {
return (tmp * tmp) % C;
}
}
만약 지수가 0이면 1을 반환하면 된다.
tmp에 지수를 반으로 나눈 값을 넣어 재귀함수를 호출한다.
만약 지수가 홀수이면 (tmp * tmp % C) * A % C 식으로 나타내고,
지수가 짝수이면 (tmp * tmp) % C 식을 나타낸다.
홀수에서 C를 먼저 나눠준 이유는 수가 long을 넘어가는 것을 방지하기 위함이다.
'문제 > 백준_자바' 카테고리의 다른 글
169. 2740(행렬곱셈) - 자바 (0) | 2022.08.02 |
---|---|
168. 1629(이항계수3) - 자바 (0) | 2022.08.01 |
166. 1780(종이의 개수) - 자바 (0) | 2022.07.31 |
165. 1992(쿼드트리) - 자바 (0) | 2022.07.30 |
164. 2630 (색종이 만들기) - 자바 (0) | 2022.07.30 |
Comments