※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 14476번 문제인 최대공약수 하나 빼기이다.
문제는 아래 링크를 확인하자.

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

 

최대공약수는 유클리드 호제법으로 빠르게 구할 수 있다.

 

어떤 한 수를 제외한 다른 모든 수의 최대공약수는 그 수의 왼쪽에 있는 모든 수의 최대공약수와 오른쪽에 있는 모든 수의 최대공약수와 같음을 관찰하자. 따라서 왼쪽부터의 i번째 수까지의 최대공약수를 계산해 둔 배열과 오른쪽부터 i번째 수까지의 최대공약수를 계산해 둔 배열을 각각 O(NlgN)에 구해두면 i번째 수를 제외한 수의 최대공약수를 각각 lgN에 계산할 수 있게 된다.

 

각 수에 대하여 그 수를 제외한 나머지 수의 최대공약수를 계산하고, 그 중 문제의 조건을 만족하는 최대공약수수의 최댓값과 그 때의 인덱스를 저장해 문제를 해결하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int gcd(int x, int y) {
    if (y) return gcd(y, x % y);
    return x;
}

int N, ans = -1, aidx;
int A[1000002], L[1000002], R[1000002];

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

    cin >> N;
    for (int i = 1; i <= N; i++) cin >> A[i];
    for (int i = 1; i <= N; i++) L[i] = gcd(L[i - 1], A[i]);
    for (int i = N; i > 0; i--) R[i] = gcd(R[i + 1], A[i]);
    for (int i = 1; i <= N; i++) {
        int val = gcd(L[i - 1], R[i + 1]);
        if (A[i] % val) {
            if (ans < val) ans = val, aidx = i;
        }
    }
    if (ans < 0) cout << ans;
    else cout << ans << ' ' << A[aidx];
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 11643 // C++] The Magical 3  (0) 2024.12.23
[BOJ 1800 // C++] 인터넷 설치  (0) 2024.12.20
[BOJ 1451 // C++] 직사각형으로 나누기  (1) 2024.12.18
[BOJ 32963 // C++] 맛있는 사과  (0) 2024.12.17
[BOJ 32661 // C++] Airfare Grants  (0) 2024.12.16

+ Recent posts