Bài toán – Số phản nguyên tố
Một số n gọi là số phản nguyên tố nếu số ước số của nó là nhiều nhất trong n số tự nhiên đầu tiên. Cho số K (K <= 2 tỷ). Hãy ghi ra số phản nguyên tố lớn nhất nhỏ hơn hoặc bằng K.
Dữ liệu vào trong file PNT.INP nội dung gồm:
– Dòng đầu tiên là số M (1 < M <= 100) – số các số cần tìm số phản nguyên tố lớn nhất của nó;
– M dòng tiếp theo lần lượt là các số K1, K2, K3, …, KM;
Dữ liệu ra trong file PNT.OUT gồm M dòng: dòng thứ i là số phản nguyên tố lớn nhất nhỏ hơn hoặc bằng Ki.
Ví dụ:
PNT.INP
1
1000
PNT.OUT
840
Thuật toán
Để giải bài toán này, ta cần tìm cách kiểm tra số nguyên dương n có phải là số nguyên tố hay không, và sau đó tìm số phản nguyên tố lớn nhất nhỏ hơn hoặc bằng K.
Cách kiểm tra số nguyên dương n có phải là số nguyên tố hay không có thể thực hiện bằng cách duyệt qua các ước số của n từ 2 đến căn bậc hai của n. Nếu n không chia hết cho bất kỳ ước số nào trong đoạn này thì n là số nguyên tố.
Để tìm số phản nguyên tố lớn nhất nhỏ hơn hoặc bằng K, ta cần duyệt qua các số từ K-1 về 2, kiểm tra từng số đó có phải là số phản nguyên tố hay không bằng cách sử dụng thuật toán kiểm tra số nguyên tố đã đề cập ở trên. Khi tìm được một số phản nguyên tố, ta có thể dừng vòng lặp và in ra kết quả.
Cài đặt bài toán với Python
import math
# Hàm kiểm tra số nguyên dương n có phải là số nguyên tố hay không
def is_prime(n):
if n < 2:
return False
for i in range(2, int(math.sqrt(n))+1):
if n % i == 0:
return False
return True
# Đọc dữ liệu vào từ file PNT.INP
with open('PNT.INP', 'r') as f:
m = int(f.readline().strip())
k_values = [int(f.readline().strip()) for i in range(m)]
# Tìm số phản nguyên tố lớn nhất nhỏ hơn hoặc bằng từng giá trị trong k_values
for k in k_values:
for n in range(k-1, 1, -1):
if is_prime(n) and k % n == 0:
print(n)
break
# Ghi kết quả ra file PNT.OUT
with open('PNT.OUT', 'w') as f:
for k in k_values:
for n in range(k-1, 1, -1):
if is_prime(n) and k % n == 0:
f.write(str(n) + '\n')
break
Cài đặt bài toán với C++
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
// Hàm kiểm tra số nguyên dương n có phải là số nguyên tố hay không
bool is_prime(int n) {
if (n < 2) {
return false;
}
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
int m, k;
ifstream fin("PNT.INP");
ofstream fout("PNT.OUT");
fin >> m;
for (int i = 0; i < m; i++) {
fin >> k;
for (int n = k - 1; n > 1; n--) {
if (is_prime(n) && k % n == 0) {
fout << n << endl;
break;
}
}
}
fin.close();
fout.close();
return 0;
}