JAVA 백준 알고리즘 문제풀이/분할 정복
[백준 BOJ 1629번] 곱셈
Xerath(제라스)
2022. 2. 23. 21:15
728x90
반응형
출처 : https://www.acmicpc.net/problem/1629
1629번: 곱셈
첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.
www.acmicpc.net
1. 문제
자연수 A를 B번 곱한 수를 알고 싶다. 단 구하려는 수가 매우 커질 수 있으므로 이를 C로 나눈 나머지를 구하는 프로그램을 작성하시오.
2. 입력
첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.
10 11 12
3. 출력
첫째 줄에 A를 B번 곱한 수를 C로 나눈 나머지를 출력한다.
4
4. 풀이
일단 분할 정복인 부분부터가 큰 힌트였다. 먼저, 이렇게 큰 수들의 곱셉 및 나눗셈들의 과정이 나오면 분할 정복을 의심해봐야 한다. 이 문제의 경우 가장 어려웠던 부분은 %계산의 시기를 정하는 부분이었고 중요한 부분은 자료형의 선택의 부분이었다. 21억~~을 고려하면서 자료형을 long으로 두어도 되는지를 생각해봐야 했다. 크게 어려운 부분은 없고 구하고자 하는 값의 지수부분을 /2씩 해가면서 1일 경우 return을 하며 다시 conquer해가는 부분만 잘 해결하면 쉽게 풀 수 있었다.
5. 소스코드
import java.io.*;
import java.util.*;
public class Main {
static long C;
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Long.parseLong(st.nextToken());
long B = Long.parseLong(st.nextToken());
C = Long.parseLong(st.nextToken());
System.out.println(result(A, B));
}
static long result(long a, long b) {
if (b == 1)
return a % C;
long temp = result(a, b / 2);
if (b % 2 == 0) {
return (temp*temp) % C; //temp*temp는 long형을 넘어가지 않기에 %C를 해주지 않아도 되지만, 아래dml return문의 경우엔 temp*temp*a가 long형을 넘어가므로 각각 %C를 해주어야 한다.
}
return (temp%C * temp%C) * a%C;
}
}
6. 배운 것
큰 수들을 다룰 땐 분할 정복을 생각해보자.
자료형의 선택을 잘 고려하고 overflow가 일어나지 않게 항상 조심하며 %계산을 해주자.
728x90
반응형