Post

[백준] 1629번 - 곱셈 [Java][C++]

[백준] 1629번 - 곱셈 [Java][C++]

문제 링크


1. 문제 풀이

간단하게 $A^B \ (\mathrm{mod}\ C)$ 를 구해야 하는 문제다. $B$ 의 크기가 매우 커질 수 있어서 반복적으로 곱하는 방식으로는 해결할 수 없는데 분할 정복을 이용한 거듭제곱이라는 테크닉을 활용하면 해결할 수 있다.


2. 코드

1. 분할 정복을 이용한 거듭제곱 [Java]

반복문을 활용해 구현했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
        int C = Integer.parseInt(st.nextToken());

        System.out.println(modPow(A, B, C));
    }

    static long modPow(long A, long B, long C) {
        long res = 1;

        while (B > 0) {
            if ((B & 1) > 0) res = res * A % C;
            A = A * A % C;
            B >>= 1;
        }

        return res;
    }
}

2. 분할 정복을 이용한 거듭제곱 [Java]

재귀를 활용해 구현했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
        int C = Integer.parseInt(st.nextToken());

        System.out.println(modPow(A, B, C));
    }

    static long modPow(long A, long B, long C) {
        if (B == 0) return 1;

        long half = modPow(A, B / 2, C);
        if (B % 2 == 1) {
            return half * half % C * A % C;
        } else {
            return half * half % C;
        }
    }
}

3. 분할 정복을 이용한 거듭제곱 [C++]

반복문을 활용해 구현했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;

long long modpow(long long a, long long b, long long c) {
    long long res = 1;

    while (b > 0) {
        if (b & 1) res = res * a % c;
        a = a * a % c;
        b >>= 1;
    }

    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int a, b, c;
    cin >> a >> b >> c;
    cout << modpow(a, b, c);
}

4. 분할 정복을 이용한 거듭제곱 [C++]

재귀를 활용해 구현했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>
using namespace std;

long long modpow(long long a, long long b, long long c) {
    if (b == 0) return 1;

    long long half = modpow(a, b / 2, c);
    if (b % 2) {
        return half * half % c * a % c;
    } else {
        return half * half % c;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int a, b, c;
    cin >> a >> b >> c;
    cout << modpow(a, b, c);
}

3. 풀이 정보

1. 분할 정복을 이용한 거듭제곱 [Java]

언어시간메모리코드 길이
Java 11108 ms14128 KB705 B

2. 분할 정복을 이용한 거듭제곱 [Java]

언어시간메모리코드 길이
Java 11104 ms14184 KB736 B

3. 분할 정복을 이용한 거듭제곱 [C++]

언어시간메모리코드 길이
C++ 170 ms2020 KB394 B

4. 분할 정복을 이용한 거듭제곱 [C++]

언어시간메모리코드 길이
C++ 170 ms2020 KB426 B

This post is licensed under CC BY 4.0 by the author.