Với kinh nghiệm nhiều năm giảng dạy và tham gia bồi dưỡng học sinh giỏi tôi viết sáng kiến kinh nghiệm với đề tài “Vận dụng thuật toán về số nguyên tố để giải các bài toán”.. Nội dung c
Trang 1ĐẶT VẤN ĐỀ
1 Lý do chọn đề tài
Số nguyên tố là một trong những vấn đề trung tâm của số học Trong thực
tế, các thuật toán về số học được ứng dụng vào việc giải quyết rất nhiều bài toán Một trong những thuật toán đó là thuật toán về số nguyên tố Đây là thuật toán được sử dụng nhiều trong các kỳ thi học sinh giỏi Tin học Do đó, việc giảng dạy để các em nắm chắc về thuật toán cũng như việc vận dụng các thuật toán đó để giải các bài toán cụ thể là điều rất quan trọng, đó cũng là cơ sở để các
em học tốt phần tin học lập trình và đạt kết quả cao trong học tập cũng như trong các kỳ thi HSG
Với kinh nghiệm nhiều năm giảng dạy và tham gia bồi dưỡng học sinh giỏi
tôi viết sáng kiến kinh nghiệm với đề tài “Vận dụng thuật toán về số nguyên tố
để giải các bài toán”
Nội dung của đề tài là kiến thức các thuật toán về số nguyên tố và việc vận dụng các thuật toán đó trong giải quyết các bài toán
Tôi hy vọng sáng kiến kinh nghiệm sẽ là tài liệu tham khảo tốt cho các giáo viên và các em học sinh trong giảng dạy và bồi dưỡng học sinh giỏi Rất mong được sự góp ý từ các đồng nghiệp
2 Cấu trúc nội dung
I Các thuật toán về số nguyên tố
1 Thuật toán kiểm tra tính nguyên tố
2 Thuật toán Sàng nguyên tố Eratosthenes
3 Phân tích một số ra thừa số nguyên tố
II Bài tập vận dụng
Dạng 1: Kiểm tra tính nguyên tố
Dạng 2: Sử dụng thuật toán sàng nguyên tố
Dạng 3: Phân tích thành các số nguyên tố
3 Mục đích nghiên cứu
Trong quá trình nghiên cứu và giảng dạy, tôi nhận thấy việc vận dụng các thuật toán về số nguyên tố vào việc giải một số bài toán rất hiệu quả Vì vậy, tôi viết đề tài này với mục đích:
- Thứ nhất, trao đổi cùng với các đồng nghiệp về việc vận dụng các thuật
về số nguyên tố vào việc giải một số bài toán
Trang 2- Thứ hai, là tài liệu cho giáo viên phục vụ giảng dạy, bồi dưỡng học sinh giỏi
4 Phương pháp nghiên cứu
Kinh nghiệm bản thân, thảo luận, sưu tầm tài liệu, thử nghiệm thực tế, rút kinh nghiệm từ các tiết dạy trên lớp
5 Giới hạn phạm vi nghiên cứu của đề tài
Đề tài chủ yếu nghiên cứu vận dụng các thuật toán được ứng dụng rộng rãi
đó là tìm kiếm tuần tự và tìm kiếm nhị phân, sắp xếp lựa chọn (Selection Sort)
và sắp xếp nhanh (Quick Sort)
Đề tài có khả năng áp dụng rộng rãi vào giảng dạy, bồi dưỡng học sinh giỏi Tin học cho giáo viên và học sinh THCS, THPT trên địa bàn toàn tỉnh Nghệ An
Trang 3NỘI DUNG
Việc nắm vững các thuật toán về số nguyên tố là điều rất quan trọng, đó là
cơ sở để các em học sinh vận dụng và giải quyết các bài toán cụ thể Sau đây, tôi xin trình bày kiến thức các thuật toán về số nguyên tố được ứng dụng rộng rãi và
hệ thống các bài tập mà tôi đã tìm hiểu và vận dụng có hiệu quả trong quá trình giảng dạy
I CÁC THUẬT TOÁN VỀ SỐ NGUYÊN TỐ
1.1 Thuật toán kiểm tra tính nguyên tố
Ta có thuật toán kiểm tra tính nguyên tố của một số n, chạy trong thời gian O(n1/2):
Function isprime (n:integer):boolean;
Begin
if n<=1 then exit(false);
for i:=2 to trunc(sqrt(n)) do
if x mod i=0 then exit(false);
exit(true);
End;
1.2 Thuật toán Sàng nguyên tố Eratosthenes
Để tìm các số nguyên tố nhỏ hơn hoặc bằng số tự nhiên N bằng sàng
Eratosthenes, ta làm như sau:
Bước 1: Tạo 1 danh sách các số tự nhiên liên tiếp từ 2 đến n: (2, 3, 4, , n)
Bước 2: Giả sử tất cả các số trong danh sách đều là số nguyên tố Trong đó, p = 2 là số nguyên tố đầu tiên
Bước 3: Tất cả các bội số của p: 2p, 3p, 4p, sẽ bị đánh dấu vì không phải là số nguyên tố
Bước 4: Tìm các số còn lại trong danh sách mà chưa bị đánh dấu và phải lớn hơn p Nếu không còn số nào, dừng tìm kiếm Ngược lại, gán cho p giá trị bằng số nguyên tố tiếp theo và quay lại bước 3
Khi giải thuật kết thúc, tất các số chưa bị đánh dấu trong danh sách là các
số nguyên tố cần tìm
Trang 4Ta có mảng P, P[i]=true (i>1) nếu I là số nguyên tố và ngược lại
Thuật toán này chỉ có độ phức tạp là O(n) thế nên ta có thể hoàn toàn thực hiện với n=108
1.3 Phân tích một số ra thừa số nguyên tố
Trang 6If (n>1) then Begin
inc(t);
coso[t]:=n; somu[t]:=x;
end;
end;
Thông tin được trả về trong mảng coso[i] và somu[i] lần lượt là cơ số và số
mũ của thừa số thứ I trong phép phân tích của n ra thừa số nguyên tố Trong trường hợp xấu nhất, với n là số nguyên tố thì thuật toán chạy trong thời gian
là O(n1/2)
Trang 7II BÀI TẬP ÁP DỤNG
Dạng 1: Kiểm tra tính nguyên tố
Bài 1 Viết chương trình nhập vào từ bàn phím số nguyên N (N>10), in ra
màn hình các số nguyên tố trong khoảng từ 1 đến N
Hướng dẫn:
Nhận xét: Học sinh sẽ áp dụng thuật toán kiểm tra tính nguyên tố của một
số để giải quyết bài toán Ta chỉ cần dùng thêm một vòng lặp chạy từ 2 đến N đặt ngoài vòng lặp kiểm tra số nguyên tố
if K<=1 then nt:=false else
for i:=2 to trunc(sqrt(K)) do if k mod i=0 then
1 Tìm số nguyên tố lớn nhất của dãy
2 Số nào xuất hiện nhiều nhất trong dãy
Dữ liệu:
Đầu vào cho bởi tệp: primemax.inp
- Dòng đầu tiên là số n
Trang 8Đầu ra cho bởi tệp: primemax.out
- Dòng thứ nhất là số nguyên tố lớn nhất của dãy, nếu không có số nguyên
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then exit(false);
Trang 10Dữ liệu: Vào từ file BEAUTY.INP
Gồm nhiều tests, mỗi test cho trên một dòng chứa một số nguyên N
Kết quả: Ghi ra file BEAUTY.OUT
Mỗi test đưa ra trên một dòng là kết quả số đẹp tìm được tương ứng của mỗi test từ file dữ liệu vào
Trang 11for i:=2 to 810 do if ktr1 then c[i]:=true;
for i:=1 to n do if max<a[i] then max:=a[i];
Trang 12Bài 4 Nguyên tố cùng nhau
Juggernaut được cô giáo Disruptor dạy toán, cô giáo định nghĩa một hàm f(x) như sau:
Với t là số lượng các số tự nhiên k (1 <= k <= x) thỏa mãn nguyên tố cùng nhau với x, nếu t là nguyên tố thì f(x) = 1, ngược lại f(x) = 0
Disruptor cho Juggernaut một số nguyên dương x, yêu cầu anh cho biết giá trị của hàm f(x), nếu trả lời sai thì Jug sẽ bị cô trả về nhà, Jug không muốn
về nhà, các bạn hãy giúp Jug giải bài toán này
Input
Dòng đầu tiên chứa số bộ test T (T <= 10)
Mỗi test gồm một dòng chứa số x (1 <= x <= 10^5)
Trang 13Giải thích khái niệm
- Nguyên tố cùng nhau của 2 số a và b là UCLN của a và b bằng 1
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then
Trang 14Yêu cầu: Cho số N, hãy giúp TMB trả lời câu đố của thầy giáo, nếu N là lũy
thừa cao của một số nguyên tố thì in ra 2 số p và q tương ứng, nếu không thì ghi 0
Giới hạn:
n <= 10^18
Input:
1 dòng duy nhất chứa n
Trang 15for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then
exit(false);
exit(true);
Trang 17trong đó K là một số nguyên dương
Phương trình này có thể có vô số nghiệm Tuy nhiên, ở đây người ta chỉ quan tâm đến các nghiệm (x,y,z) mà trong đó các số x,y,z đều là các số nguyên
Dữ liệu vào cho trong file văn bản EQUA.INP trong đó chứa duy nhất số K Kết quả ghi ra file văn bản EQUA.OUT chứa N + 1 dòng (N là số nghiệm tìm được), trong đó:
Dòng thứ i trong N dòng đầu tiên chứa 3 số nguyên cho biết bộ
nghiệm thứ i tìm được
Dòng thứ N + 1 chứa 3 số 0 cho biết điểm kết thúc file output
Các số trên cùng một dòng cách nhau bởi khoảng trắng
Ví dụ:
Trang 18for i:=2 to MAXK do
if (nguyento(i)) then begin
Trang 19từ T như sau
Là một người yêu thích số học anh ta thường chọn mật khẩu P là một số nguyên tố và đem dấu vào một xâu ký tự T sao cho P chính là số nguyên tố có giá trị lớn nhất trong số các số nguyên tố tạo được từ các xâu con của T (xâu con của một xâu ký tự T là một chuỗi liên tiếp các ký tự trong T)
Ví dụ: xâu T=”Test1234#password5426” chứa mật khẩu là 23 vì T chứa các xâu con ứng với các số nguyên tố 2,3,23 và 5
Yêu cầu: Cho một xâu ký tự T chiều dài không quá 250 ký tự Tìm mật khẩu
P đã dấu trong xâu T biết P có giá trị nhỏ hơn 105 Dữ liệu cho đảm bảo T chứa
ít nhất 1 số nguyên tố
Dữ liệu: Vào từ file văn bản PASSWORD.INP gồm 1 dòng duy nhất là xâu T Kết quả: Ghi ra file văn bản PASSWORD.OUT chứa số P tìm được
Trang 20Để duyệt qua các xâu con, ta duyệt qua vị trí đầu:
for i:=1 to length(t) do {i là vị trí đầu của xâu con}
Với mỗi vị trí đầu i, ta duyệt qua vị trí cuối của xâu con:
Trang 23Dạng 2: Sử dụng thuật toán sàng nguyên tố
Bài 1 HSPC14J-Sàng ( http://vn.spoj.com/problems/HSPC14J/ )
Sàng của Eratosthenes là thuật toán nổi tiếng để tìm tất cả các số nguyên
tố nhỏ hơn N Thuật toán như sau:
1 Ghi ra tất cả các số nguyên giữa 2 và N
2 Tìm số nhỏ nhất chưa bị gạch và gọi nó là P (P là số nguyên tố)
3 Gạch bỏ P và tất cả các bội số của nó mà chưa bị gạch
4 Nếu còn số chưa bị gạch bỏ, chuyển sang bước 2
Viết một chương trình, cho N và K, tìm số nguyên thứ K bị gạch
Trang 24Vườn quốc gia Xuân Sơn, tỉnh Phú Thọ nổi
tiếng với vẻ đẹp hoang sơ tự nhiên, có hệ sinh
thái phong phú và đa dạng Du khách khi tới đây
có thể tận mắt chiêm ngưỡng khu rừng chò trỉ
đẹp nhất miền bắc cùng một số loài thực vật số
lượng lớn như cây rau sắng, dẻ, mộc lan… Ngoài
Trang 25sức hấp dẫn của hệ động thực vật phong phú, Xuân Sơn còn có nhiều cảnh quan thiên nhiên kỳ thú thu hút khách du lịch như núi Voi, núi Ten và núi Cẩn Cùng với các con suối như suối Lấp, suối Thang; với nhiều thác nước có độ cao trên 50m Màu thác bạc hoà quyện với màu xanh của rừng già làm cho phong cảnh nơi đây vừa hùng vĩ vừa thơ mộng
Tại đây, các nhà khảo cổ học đã phát hiện ra một số kho báu bí mậtcủa được các vua Hùng xây dựng rất kiên cố và không thể phá bỏ Họ cho rằng trong đó có thể là những khối tài sản về lịch sử và văn hóa rất có giá trị và họ tìm cách mở cánh cửa của những kho báu đó
Trên cửa mỗi kho báu có một bảng gồm 2 hàng, hàng 1 đã
ghi sẵn số nguyên dương N (≤106), hàng 2 chứa 2 khoá số K1 và
K2 như hình bên
N
Trong khi khảo sát, các nhà khảo cổ đã phát hiện một phiến đá có ghi cách
để mở khoá như sau: cửa có bảng chứa số N sẽ tương ứng với K1 và K2 là:
- Điều chỉnh khoá số K1 về số bằng số lượng ước nguyên tố của N;
- Điều chỉnh khoá số K2 về số bằng tổng các ước nguyên tố của N thì cánh cửa sẽ tự động mở ra và nhà khảo cổ có thể vào bên trong kho báu một cách dễ dàng
Ví dụ: Ở nhà kho trên cửa ghi số N=12, có các ước của N là 1, 2, 3, 4, 6, 12 chỉ có 2 ước nguyên tố là 2 và 3 nên K1=2 và K2=5
Dữ liệu: vào từ filevăn bản PASS.INPchứa duy nhất một số nguyên dương
Có 30% số các test ứng với 30% số điểm của bài có 𝑁 ≤ 1000;
Có 40% số test khác ứng với 40% số điểm của bài có 𝑁 ≤ 104;
Có 30% số test còn lại ứng với 30% số điểm của bài có 𝑁 ≤ 106
Hướng dẫn:
Bài này yêu cầu chỉ đơn giản là xây dựng sàng lọc ra các số nguyên tố nhỏ hơn hoặc bằng N Đếm số lượng các số nguyên tố và tính tổng các số nguyên tố
đó
Trang 27Một số nguyên dương N được gọi là số "gần hoàn hảo" nếu thỏa mãn điều kiện: 2* N ≤ A, với A là tổng các ước số của N
Chẳng hạn: 12 là một số "gần hoàn hảo" vì: 2*12 < 1+2+3+4+6+12
Yêu cầu: Với K số nguyên dương, hãy kiểm tra xem các số nguyên dương
đó có phải là số "gần hoàn hảo" hay không?
Dữ liệu vào: Từ tệp GHH.INP có cấu trúc như sau:
- Dòng đầu tiên chứa số nguyên dương K (K ≤ 100)
- Dòng thứ hai chứa K số nguyên dương A 1 , A 2 ,…, A K (A i ≤ 10 9 với 1≤ i ≤ K)
Dữ liệu ra: Ghi vào tệp GHH.OUT gồm K dòng, dòng thứ i ghi số 1 nếu A i là
số "gần hoàn hảo", ngược lại ghi số 0
Ta phân tích các số nguyên dương N thành tích các thừa số nguyên tố, sau
đó áp dụng công thức để tính tổng các ước của nó
Để thuật toán nhanh hơn có thể áp dụng sàng số nguyên tố
Trang 30Yêu cầu: Cho hai số nguyên l và r (2 ≤ l ≤ r ≤ 50 000) Hãy tìm số nguyên
tố tốt nhất trong khoảng [l, r] Nếu trong khoảng này không có số nguyên tố nào
Trang 32Input
Số nguyên dương n ( 1 < n < 10 )
Output
Dòng đầu tiên ghi ra số k là số cách tìm được
K dòng tiếp theo mỗi dòng ghi ra 1 cách điền các số vào các vòng tròn nhỏ Cách điền nào có thứ tự từ điển nhỏ hơn thì xếp trước Nếu K > 10000 thì chỉ cần ghi ra 10000 cách đầu tiên
Ví dụ
Trang 36lúc khi có thời gian rãnh Hôm nay, giờ giải lao trên lớp, Bờm quay sang đố Tuấn, với số tự nhiên N cho trước thì số chính phương lớn nhất được biểu diễn bằng tích của một tập các số tự nhiên phân biệt từ 1 đến N là bao nhiêu? Tuấn suy nghĩ mãi mà chưa trả lời được câu đố và thời gian thì ít quá
Yêu cầu: Cho một số nguyên N, hãy giúp Tuấn đưa ra số chính phương lớn
nhất là tích của một tập các số tự nhiên phân biệt từ 1 đến N Số đó có thể rất lớn nên chỉ cần xuất ra phần dư khi chia số đó cho 1000000007
Dữ liệu: Từ file văn bản SOCP.INP có cấu trúc:
Một dòng duy nhất chứa số nguyên dương N (N ≤ 4.104)
Trang 37Kết quả: Ghi vào file văn bản SOCP.OUT có cấu trúc:
Một dòng duy nhất là kết quả bài toán sau khi đã mod 1000000007
Ví dụ
SOCP.INP SOCP.OUT
Subtask 1 (2 điểm): Giả thiết N≤ 10 2
Subtask 2 (2 điểm): Giả thiết N≤ 10 3
Subtask 3 (2 điểm): Giả thiết N≤ 4.10 4
Thuật toán:
- Phân tích số N! thành tích các thừa số nguyên tố, ghi nhận số lượng mỗi
số bằng cách dùng sàng nguyên tố Giả sử các thừa số đó là P1, P2, …, Pk với các
số mũ tương ứng là a1, a2, …, ak
- Nếu ai lẻ thì giảm ai một đơn vị với mọi i = 1, 2, …, k
- Số chính phương lớn nhất cần tìm là tích các thừa số nguyên tố của các các số nguyên tố có số mũ chẵn lớn hơn 0 Chú ý khi tính ta mod với
Trang 39if odd(a[i]) then dec(a[i]);
if a[i]>0 then kq:=(kq*mu(p[i],a[i])) mod k;
Trang 40Kết quả ghi ra tệp văn bản PHANTICH.OUT gồm các dòng, mỗi dòng ghi
một thừa số nguyên tố tiếp đến là số mũ tương ứng Các số trên cùng dòng cách nhau qua dấu cách
for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then exit(false);
Trang 42Bài 2 Biểu diễn số
Cho một số nguyên k, hãy tìm cách biểu diễn k thành tổng 3 số nguyên tố đôi một khác nhau
Dữ liệu : Vào từ file văn bản PRIME.INP chứa duy nhất 1 số là k
Trang 44Bài 3 Dãy nguyên tố
Cho số tự nhiên k và dãy A gồm N (N < 104) số tự nhiên không vượt quá
32000
Yêu cầu: Tìm k số nguyên tố nhỏ nhất khác nhau xuất hiện trong dãy A
Dữ liệu vào từ file văn bản DAYNT.INP:
Dòng đầu tiên chứa một số tự nhiên k (1< k < N)
N dòng tiếp theo, mỗi dòng chứa một số tự nhiên là một phần tử của
dãy A
Kết quả ghi ra file văn bản DAYNT.OUT: Đưa ra trên cùng một dòng k số
nguyên tố tìm được theo thứ tự tăng dần, các số cách nhau ít nhất một ký tự trống
Lưu ý: Dữ liệu vào đảm bảo luôn tìm được k số nguyên tố thỏa mãn
Trang 45Var D : Array[2 32000] of byte;
for i:=2 to trunc(sqrt(n)) do
if n mod i =0 then exit(false);
Trang 46Với số nguyên dương x, gọi f(x,k) là số cách phân tích số x thành tổng các
số nguyên tố mà mỗi số nguyên tố có trong tổng không quá k lần
Dữ liệu vào: Từ file văn bản KSNT.INP có cấu trúc như sau:
Dòng đầu tiên ghi 2 số nguyên dương theo thứ tự N, k
Dòng thứ 2 ghi N số nguyên dương a1, a2,…, aN.( 1 < aI ≤ 100)
Kết quả: Ghi ra file văn bản KSNT.OUT, gồm N số nguyên viết trên một
dòng, số thứ i là f(ai,k)
Cả 2 file dữ liệu thứ tự các số trên một dòng tính từ trái qua phải và cách nhau một dấu cách
Ví dụ:
Trang 48if j*NTO[1]>100 then break;
Trang 49END
Bài 5 Số ước
Cho số nguyên dương N Giai thừa của N, kí hiệu là N!, là tích của các số tự nhiên từ 1 đến N Gọi T là số lượng ước lớn hơn 1 của N! Ví dụ với N = 4, ta có
4! = 24 Như vậy 4! có 7 ước lớn hơn 1 là: 2, 3, 4, 6, 8, 12, 24
Yêu cầu: Cho N, hãy xác định T
Dữ liệu: Vào từ file văn bản DIVISORS.INP trong đó chứa duy nhất số N (N
[n/p] + [n/p2] + [n/p3] +
Trong đó [n/p] ký hiệu phần nguyên của n/p, nói cách khác trong ngôn ngữ Pascal [n/p] bằng n div p Công thức trên được giải thích như sau: [n/p] là số lượng số từ 1 đến n chia hết cho p, [n/p2] là số lượng số từ 1 đến n chia hết cho
p2, mỗi số này đều đóng góp một thừa số nguyên tố p phân biệt cho n!
for i:=2 to trunc(sqrt(n)) do
if n mod i = 0 then exit;