Phân Tích Số 2019 và Tính Số Cách Sắp Xếp Hàng Hóa

Bài toán Phân Tích Số 2019

Mô tả bài toán: Phân tách số 2019 thành tổng của 3 số nguyên dương khác nhau, trong đó mỗi số không chứa chữ số 2 hoặc 4. Hỏi có bao nhiêu cách phân tách khác nhau? Lưu ý rằng việc hoán vị 3 số được coi là cùng một cách.

Giải pháp: Chúng ta cần kiểm tra tất cả các tổ hợp có thể của 3 số nguyên dương khác nhau có tổng bằng 2019 và không chứa chữ số 2 hoặc 4.

#include <iostream>
using namespace std;

bool hopLe(int n) {
    while (n > 0) {
        int chuSo = n % 10;
        if (chuSo == 2 || chuSo == 4) {
            return false;
        }
        n /= 10;
    }
    return true;
}

int main() {
    int ketQua = 0;
    int a, b, c;
    
    for (a = 1; a <= 673; a++) {
        if (hopLe(a)) {
            for (b = a + 1; b <= 1346; b++) {
                if (hopLe(b)) {
                    c = 2019 - a - b;
                    if (c > b && hopLe(c)) {
                        ketQua++;
                    }
                }
            }
        }
    }
    
    cout << ketQua;
    return 0;
}

Kết quả: 40785

Giải thích: Chúng ta chỉ cần duyệt qua hai số đầu tiên, số thứ ba được tính bằng 2019 - a - b. Điều kiện c > b đảm bảo các số khác nhau và không cần kiểm tra hoán vị.


Bài toán Sắp Xếp Hàng Hóa

Mô tả bài toán: Cho n hộp hàng hóa, mỗi hộp là hình lập phương. Cần xếp chúng thành một hình hộp chữ nhật với kích thước L×W×H sao cho n = L×W×H. Hỏi có bao nhiêu cách xếp?

Giải pháp: Tìm tất cả các tổ hợp ba số có tích bằng n.

#include <iostream>
using namespace std;

#define N 2021041820210418
typedef long long ll;

int main() {
    ll ketQua = 0;
    
    for (ll i = 1; i * i * i <= N; i++) {
        if (N % i == 0) {
            for (ll j = i; i * j * j <= N; j++) {
                if (N / i % j == 0) {
                    ll k = N / i / j;
                    if (i == j && j == k) {
                        ketQua++;
                    } else if (i == j || i == k || j == k) {
                        ketQua += 3;
                    } else {
                        ketQua += 6;
                    }
                }
            }
        }
    }
    
    cout << ketQua;
    return 0;
}

Kết quả: 2430

Giải thích: Chúng ta duyệt qua các ước số của n, sử dụng tối ưu hóa vòng lặp để giảm số lần lặp. Sau khi tìm được i và j, k được tính trực tiếp. Công thức đếm các trường hợp khác nhau dựa trên việc các số có bằng nhau hay không.

Thẻ: C++ toán tổ hợp phân tích số giải thuật tối ưu vòng lặp

Đăng vào ngày 2 tháng 7 lúc 19:42