ĐỒ ÁN MÔN HỌC NM CNTT1
LỚP CỬ NHÂN TÀI NĂNG KHÓA 2012
Giảng
viên ra đề:
ThS. Trương Phước
Hưng
Bài 1:
Cho số tự nhiên A. Hãy tìm số tự
nhiên N nhỏ nhất sao cho N lũy thừa
N (nhân N cho chính nó N lần) chia hết cho A.
Hãy viết chương trình tìm số
N đó và xuất ra màn hình. Trong đó A có giá trị: 1 ≤
A ≤ 109
Ví
dụ:
Số nhập vào là A
|
Số xuất ra là N
|
8
|
4
|
13
|
13
|
Bài làm
-
Nhận xét ban đầu:
o
AA luôn chia hết cho A nên chắc
chắn kết quả N ≤ A. Vậy ta có thể lặp tìm N từ 1 đến A, gặp số N nào thoả NN
chia hết A thì ta dừng. Nhưng cách làm này gặp 2 vấn đề: NN tăng rất
nhanh và nếu lặp từ 1 đến 109 thì chương trình sẽ chạy khá chậm.
o
Do chỉ cần xét NN có chia hết
cho A hay không mà không cần quan tâm kết quả này nên ta có thể phân tích N và
A ra thừa số nguyên tố để kiểm tra tính chia hết. Như vậy sẽ không lo NN
tràn số. Nhưng chương trình vẫn phải duyệt từ 1 đến A nên vẫn chậm.
-
Đầu tiên, ta sẽ phân tích A và N ra tích
các thừa số nguyên tố để dễ xét tính chia hết:
A = p1x1
p2x2 … pkxk
N = q1y1
q2y2 … qmxm
=> NN = q1y1*N
q2y2*N … qmxm*N
o Trong cách phân tích này, ta thấy rằng mọi thừa số nguyên tố pi
của A đều phải chứa trong N. Bởi
vì nếu không có pi thì tất cả các số nguyên tố qj đều
không chia hết cho pi => NN không chia hết cho A. Vậy
nếu đặt
r = p1p2…pk, ta có N ≥ r. Ngoài ra, để NN chia hết cho A thì mọi số mũ của
pi trong NN phải lớn hơn hoặc bằng số mũ của pi
trong A. (*)
- Vậy N sẽ có dạng: r*t = p1p2…
pk* t.
o Trong trường hợp r ≥ xi ∀i thì ta chỉ cần đặt N = r thì khi đó NN = p1rp2r… pkr => mọi số mũ của pi trong NN đều lớn hơn hoặc bằng số mũ của pi trong A => NN chia hết cho A theo (*).
o Trong trường hợp r ≥ xi ∀i thì ta chỉ cần đặt N = r thì khi đó NN = p1rp2r… pkr => mọi số mũ của pi trong NN đều lớn hơn hoặc bằng số mũ của pi trong A => NN chia hết cho A theo (*).
o
Trong trường hợp ngược lại
(tức ∃i : r < xi), kết quả sẽ là N=r*t với t>1. Lúc
này, ta sẽ phải xét t trong khoảng [2,max(xi)] (chỉ xét đến max(xi)
là vì khi t=max(xi) thì zi*t ≥ xi ∀i => NN
đã chia hết cho A, vậy không cần tìm t lớn hơn max(xi) nữa). Khi đó,
với mỗi ước pi của A, ta xét số mũ của pi trong NN
= p1 r*tp2r*t… pkr*t
tr*t có lớn hơn số
mũ của pi trong A không. Nếu mọi số mũ pi trong NN
đều lớn hơn hoặc bằng số mũ của pi trong A thì NN sẽ chia
hết cho A (theo (*)) => N=r*t chính là giá trị nhỏ nhất để NN
chia hết cho A.
Mã nguồn
#include <iostream> #include <cmath> using namespace std; int demMu(int& iSo, int iUoc) { int iDem = 0; while (iSo % iUoc == 0) { iSo /= iUoc; iDem++; } return iDem; } void main() { int iA, iMaxMu = 1, iR = 1; cout << "Nhap gia tri cua A: "; cin >> iA; double dCanA = sqrt(iA * 1.0); int iABanDau = iA; for (int i = 2; i <= dCanA; i++) if (iA % i == 0) { int iMu = demMu(iA, i); iR *= i; if (iMu > iMaxMu) iMaxMu = iMu; } if (iA > 1) iR *= iA; if (iMaxMu > iR) for (int k = 2; k <= iMaxMu; k++) { bool bEnd = true; iA = iABanDau; for (int i = 2; i <= dCanA; i++) if (iA % i == 0) { int iC = iR * k; int iMuA = demMu(iA, i); int iMuC = demMu(iC, i); if (iMuC * iR * k < iMuA) bEnd = false; } if (bEnd) { iR *= k; break; } } cout << "N nho nhat thoa N^N chia het cho A la: "; cout << iR << endl; }
No comments:
Post a Comment