Phân tích n =A+B sao cho UCLN(A, B) là lớn nhất

Học lập trình

Bài toán ((Thi HSG MOSKVA)

Cho số tự nhiên n. Hãy phân tích n =A+B sao cho UCLN(A, B) là lớn nhất. Với 2≤ n≤ 10^9.

Thuật toán

Ta có thể giải quyết bài toán này bằng cách sử dụng thuật toán Euclid để tìm ước số chung lớn nhất của hai số A và B. Tuy nhiên, nếu ta cố định A và B, thì việc tìm ước số chung lớn nhất của chúng sẽ trở nên khó khăn. Thay vào đó, chúng ta có thể sử dụng một số kỹ thuật toán học để giải quyết bài toán này một cách hiệu quả hơn.

Ta nhận thấy rằng, để UCLN(A,B) là lớn nhất, thì A và B cần phải gần bằng nhau nhất có thể. Nếu ta giả sử A là số lớn hơn, thì B phải rất nhỏ so với A để có thể tạo ra UCLN(A,B) lớn nhất. Tương tự, nếu B là số lớn hơn, thì A phải rất nhỏ so với B để tạo ra UCLN(A,B) lớn nhất. Vì vậy, ta có thể tìm kiếm A và B bằng cách duyệt qua các số từ 1 đến n/2 và tính toán UCLN của từng cặp số.

Ta sử dụng thuật toán Euclid để tính toán UCLN của hai số. Thuật toán này hoạt động bằng cách lặp đi lặp lại cho đến khi một trong hai số bằng 0. Khi đó, số còn lại sẽ là UCLN của hai số ban đầu.

Cài đặt bài toán với Python

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

def max_gcd(n):
    best_gcd = 1
    best_a = 1
    for a in range(2, n//2 + 1):
        b = n - a
        if gcd(a, b) > best_gcd:
            best_gcd = gcd(a, b)
            best_a = a
    return (best_a, n - best_a)

n = int(input())
print(max_gcd(n))

Cài đặt bài toán với C++

#include <iostream>
using namespace std;

int gcd(int a, int b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

pair<int, int> max_gcd(int n) {
    int best_gcd = 1;
    int best_a = 1;
    for (int a = 2; a <= n/2; a++) {
        int b = n - a;
        if (gcd(a, b) > best_gcd) {
            best_gcd = gcd(a, b);
            best_a = a;
        }
    }
    return make_pair(best_a, n - best_a);
}

int main() {
    int n;
    cin >> n;
    pair<int, int> result = max_gcd(n);
    cout << result.first << " " << result.second << endl;
    return 0;
}

Cài đặt bài toán với Pascal

#include <iostream>
using namespace std;

int gcd(int a, int b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

pair<int, int> max_gcd(int n) {
    int best_gcd = 1;
    int best_a = 1;
    for (int a = 2; a <= n/2; a++) {
        int b = n - a;
        if (gcd(a, b) > best_gcd) {
            best_gcd = gcd(a, b);
            best_a = a;
        }
    }
    return make_pair(best_a, n - best_a);
}

int main() {
    int n;
    cin >> n;
    pair<int, int> result = max_gcd(n);
    cout << result.first << " " << result.second << endl;
    return 0;
}

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *