백준 1629번 : 곱셈 / C++

2023. 3. 2. 00:01개인공부/코딩테스트

https://www.acmicpc.net/problem/1629

 

1629번: 곱셈

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.

www.acmicpc.net

분할정복으로 거듭제곱을 빠르게 계산하는 문제인데 2가지 방법으로 해결이 가능했다. 첫번째는 b를 2로 나누어주어 정답을 구하는 방법이고 2번째 방법은 2진법과 비트연산자를 활용해서 답을 구하는 방법이있었다.

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
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<map>
using namespace std;
 
int A, B, C;
map<intlong long> M;
 
int Calculate(int a, int b, int c)
{
    if (b == 1)
        return a%c;
    else if (M.find(b) != M.end())
        return M.find(b)->second;
    else if( b % 2 ==0)
    {
        long long num = Calculate(a, b / 2, c) %c;
        long long value = (num * num) % c;
        M.insert(make_pair(b, value));
        return value;
    }
    else
    {
        long long num = Calculate(a, (b - 1/ 2, c)%c;
        long long value = ((num * num)%c * a) % c;
        M.insert(make_pair(b, value));
        return value;
    }
    return  0;
}
 
 
int main(void)
{
    cin >> A >> B >> C;
 
    cout << Calculate(A, B, C);
    return 0;
}
cs

 

 

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
28
29
#include <iostream>
 
using namespace std;
using ll = long long;
 
 
ll binpow(ll a, ll b, ll m) {
    a %= m;
    ll res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}
 
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int A, B, C;
    cin >> A >> B >> C;
 
    cout << binpow(A, B, C);
    return 0;
}
 
cs