November 25, 2012

ĐỒ ÁN MÔN HỌC NM CNTT1 - BÀI 1


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