관리 메뉴

사과하는 제라스

[백준 BOJ 1629번] 곱셈 본문

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
    반응형