알고리즘

백준 1629: 곱셈 [C++]

avocado8 2024. 11. 2. 13:19

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

 

 

큰 수의 곱셈 문제가 있을 때 떠올리면 좋은 건 분할정복과 비트마스킹이다.

a를 b번 곱할 때 반복문으로 b번 곱하는 것이 아니라, 지수를 반으로 나눠서 거듭제곱하는 방식이다. 물론 이때 지수가 짝수이면 그냥 반 갈라도 되지만 지수가 홀수이면 1을 하나 빼서 나눈 뒤 마지막에 한번 더 곱해줘야 한다.

처음에는 그냥 비트마스킹만 생각했는데 그럼 2의 거듭제곱만으로 계산해야 하니 귀찮았다..

 

단 숫자가 아주 커질 수 있기 때문에 그냥 계산하면 오류가 날 수 있으므로 계산 과정에서 매번 c로 나눈 나머지를 사용하도록 해서 오버플로가 나지 않게 해준다.

 

b & 1 이라는건 비트마스킹에서 첫번째 비트가 1인 수와 and를 했을 때 true 즉 0이 아니라는 뜻으로, b의 1번째 비트가 1이라는 의미이다. 이는 곧 b가 홀수임을 의미한다.

#include <iostream>
using namespace std;
typedef long long ll;

ll multi(ll a, ll b, ll c){
    ll result = 1;
    a %= c;
    while(b){
        if (b&1){ //b가 홀수면
            result = (result * a) % c;
        }
        a = (a*a)%c;
        b = b >> 1; //b를 반으로 나눔
    }
    return result;
}

int main() {
    ll a, b, c;
    cin >> a >> b >> c;
    //a를 b번 곱한 수를 c로 나눈 나머지
    ll result = multi(a, b,c );
    cout << result;
    return 0;
}

'알고리즘' 카테고리의 다른 글

프로그래머스: 베스트앨범 [C++]  (0) 2025.01.03
백준 1655: 가운데를 말해요 [C++]  (1) 2024.07.26
백준 1052: 물병 [C++]  (0) 2024.07.25
백준 1043: 거짓말 [C++]  (2) 2024.07.24
백준 1260: DFS와 BFS [C++]  (0) 2024.07.19