C++_코딩테스트/분할정복(Divide and Conquer)

[백준 1629번/C++] 분할 정복 곱셈

예상밖의C 2024. 2. 4. 21:29

처음 이 문제를 봤을 때 분할 정복으로 나눌 방법을 찾지 못해서 DC함수를 만들고 반복문 안에서 DC함수를 불러왔다.

DC함수 안에서는 계속 곱한 수의 나머지에 A를 곱하고 %C를 한.. 

작은 수에서는 괜찮았는데 아무래도 A, B, C 모두 최대 21억이다보니 long long으로 받아도 안됐었다.

그래서 반복문은 포기, B를 계속 2로 나눠서 수를 낮추는 방법으로 했다.

 

여기서 계속 %C를 해주는 것을 모듈러 연산이라고 하는데, 

모듈러 연산: 정수들 간의 산술 연산을 특정 모듈로 나눈 나머지를 구하는 연산

으로, 결과를 0부터 모듈 값까지 범위로 제한한다. 이를 통해 오버플로를 방지할 수 있다.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;


int DC(int A, int B, int C)
{
    if (B == 1) return A % C;

    long long tmp = DC(A, B / 2, C) % C;

	// 예를 들면 7을 2로 나눈 몫은 3으로, 3+3이 되면 1이 모자라므로 A를 한번 더 곱해줌
    if (B % 2) return tmp * tmp % C * A % C;
    else return tmp * tmp % C;

}

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

    int A{}, B{}, C{};
    cin >> A >> B >> C;
    
    cout << DC(A, B, C);
}

 

알게 된 점: 모듈러 연산(많이 해도 계산의 오류가 날 확률 적음)