티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/2824

 

2824번: 최대공약수

첫째 줄에 N이 주어진다.(1 ≤ N ≤ 1000) 둘째 줄에는 N개의 정수가 공백으로 구분되어 주어진다. 이 수는 모두 1,000,000,000보다 작고, N개의 수를 곱하면 A가 된다. 셋째 줄에 M이 주어진다.(1 ≤ M ≤ 1

www.acmicpc.net

 

풀이

수가 매우 크기 때문에 $a, b$를 long long으로 표현할 수 없습니다.

$a, b$를 소인수분해한 뒤, 겹치는 소인수를 모두 곱해주는 방식으로 정답을 구하면 됩니다.

 

근데 출력조건이 너무 불친절합니다. 9자리까지 출력해야 하는데, 만약 정답이 123,456이면 "123456"을, 1,000,123,456이면 leading zero를 포함하여 "000123456"을 출력해야 합니다. 계산 과정 중 9자리를 넘어가면 따로 체킹을 하고 0을 출력해주도록 합시다.

 

정답 코드

#include <bits/stdc++.h>

#define ft first
#define sd second
using namespace std;
using ll = long long;
const int MOD = 1'000'000'000;
bool c = false;
int n, m;
map<ll, int> a, b;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    ll x;
    for (int i = 0; i < n; i++) {
        cin >> x;
        for (int j = 2; j * j <= x; j++) {
            while (x % j == 0) {
                a[j]++;
                x /= j;
            }
        }
        if (x > 1) a[x]++;
    }
    cin >> m;
    for (int i = 0; i < m; i++) {
        cin >> x;
        for (int j = 2; j * j <= x; j++) {
            while (x % j == 0) {
                b[j]++;
                x /= j;
            }
        }
        if (x > 1) b[x]++;
    }
    auto pa = a.begin(), pb = b.begin();
    ll ans = 1;
    while (pa != a.end() && pb != b.end()) {
        if (pa->ft > pb->ft) {
            pb++;
        } else if (pa->ft < pb->ft) {
            pa++;
        } else {
            int cnt = min(pa->sd, pb->sd);
            while (cnt--) {
                ans *= pa->ft;
                if (ans >= MOD) {
                    c = true;
                    ans %= MOD;
                }
            }
            pa++;
            pb++;
        }
    }
    if (c) {
        cout.width(9);
        cout.fill('0');
    }
    cout << ans;
}
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함