Bài toán từ kỳ thi Olympic Tin học Blue Bridge lần thứ 5 (nhóm B) đặt ra tình huống thú vị về phép tính phân số. Khi thực hiện phép nhân 1/4 × 8/5, một học sinh đã ghép các tử số và mẫu số thành 18/45 - kết quả tình cờ chính xác. Vấn đề đặt ra: Với tử số và mẫu số đều là chữ số từ 1-9, có bao nhiêu phép tính tương tự thỏa mãn điều kiện này?
Điều kiện ràng buộc:
- Không xét trường hợp tử số bằng mẫu số (ví dụ: 2/2 × 3/3)
- Hai phép tính như a/b × c/d và c/d × a/b được tính riêng
- Kết quả phải là số nguyên chẵn do tính đối xứng
Phân tích giải pháp:
Phương pháp 1: Sử dụng ước chung lớn nhất (UCLN)
Chuyển đổi phép tính thành so sánh tỷ lệ:
(a×c)/(b×d) = (10a+c)/(10b+d)
Thay vì so sánh trực tiếp số thực, ta rút gọn phân số bằng UCLN để tránh lỗi làm tròn:
#include <iostream>
int ucln(int x, int y) {
while (y != 0) {
int temp = y;
y = x % y;
x = temp;
}
return x;
}
int main() {
int ket_qua = 0;
for (int i = 1; i <= 9; ++i)
for (int j = 1; j <= 9; ++j)
for (int k = 1; k <= 9; ++k)
for (int l = 1; l <= 9; ++l) {
if (i == j || k == l) continue;
int tu1 = i * k;
int mau1 = j * l;
int uoc1 = ucln(tu1, mau1);
int tu2 = i * 10 + k;
int mau2 = j * 10 + l;
int uoc2 = ucln(tu2, mau2);
if (tu1/uoc1 == tu2/uoc2 && mau1/uoc1 == mau2/uoc2)
++ket_qua;
}
std::cout << ket_qua;
return 0;
}
Phương pháp 2: Duyệt đệ quy
Sử dụng thuật toán quay lui để thử mọi bộ 4 chữ số, kiểm tra điều kiện qua biểu diễn số thực:
#include <iostream>
#include <vector>
int so_ket_qua = 0;
std::vector<int> bo_so(4);
bool kiem_tra_hop_le() {
return bo_so[0] != bo_so[1] && bo_so[2] != bo_so[3];
}
void duyet(int vi_tri) {
if (vi_tri == 4) {
if (kiem_tra_hop_le()) {
double kq1 = static_cast<double>(bo_so[0] * bo_so[2])
/ (bo_so[1] * bo_so[3]);
double kq2 = (bo_so[0] * 10.0 + bo_so[2])
/ (bo_so[1] * 10.0 + bo_so[3]);
if (std::abs(kq1 - kq2) < 1e-9)
++so_ket_qua;
}
return;
}
for (int num = 1; num <= 9; ++num) {
bo_so[vi_tri] = num;
duyet(vi_tri + 1);
}
}
int main() {
duyet(0);
std::cout << so_ket_qua;
return 0;
}
Cả hai phương pháp đều cho kết quả 14 bộ số thỏa mãn. Phương pháp UCLN tối ưu hơn nhờ tránh so sánh số thực, trong khi cách duyệt đệ quy minh họa rõ tư duy quay lui cho bài toán tổ hợp nhỏ.