ĐỒ Á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