SKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tốSKKN Ứng dụng lý thuyết toán để giải các bài toán tin Phần 2 Số nguyên tố
Trang 1I.2/ Mục tiêu nghiên cứu
I.3/ Nhiệm vụ nghiên cứu
I.4/ Đối tượng nghiên cứu
I.5/ Các phương pháp nghiên cứu
II PHẦN NỘI DUNG
II.1/ Lịch sử của vấn đề nghiên cứu
II.2/ Cơ sở lý luận của đề tài
II.3/ Thực trạng của vấn đề nghiên cứu
II.4/ Nội dung nghiên cứu và kết quả nghiên cứu
A/ NỘI DUNG NGHIÊN CỨU
Trang 2I PHẦN ĐẶT VẤN ĐỀ
I.1/ Lý do chọn đề tài
Để tiếp tục hoàn chỉnh chuyên đề bồi dưỡng HSG chuyên Tin “ỨNG DỤNG
LÝ THUYẾT TOÁN ĐỂ GIẢI CÁC BÀI TOÁN TIN”; qua quá trình nghiên cứu, giảng dạy, tham khảo ý kiến đồng nghiệp, tôi thấy rằng đa số các bài toán trong tin học về số thường đề cập nhiều đến số nguyên tố, xử lí trên các số nguyên tố Chính
vì vậy tôi tiếp tục chọn viết tiếp đề tài về chuyên đề “ỨNG DỤNG LÝ THUYẾT
TOÁN ĐỂ GIẢI CÁC BÀI TOÁN TIN” (Phần 2: Số nguyên tố)
I.2/ Mục tiêu nghiên cứu
Như đã biết, toán học có ảnh hưởng rất lớn đến mọi lĩnh vực của cuộc sống Các bài toán tin nếu có được thuật toán dựa trên cơ sở lý thuyết toán học vững chắc
sẽ đem lại kết quả tốt hơn rất nhiều so với các thuật toán khác Giúp các em học sinh
có kiến thức tốt, tư duy tốt về lập trình; số nguyên tố và xử lí trên các số nguyên tố là một trong những vấn đề về số mà bất cứ người lập trình tin học đều cần phải xử lý
I.3/ Nhiệm vụ nghiên cứu
Trước hết là thực hiện đổi mới phương pháp giảng dạy Tin học làm cho học sinh sáng tạo tìm những kết quả, lời giải hay trên một “dạng bài toán tin có sử dụng toán học”; giúp bản thân nắm vững hơn nữa về lập trình, tư duy thuật toán, số nguyên tố, xử lí số nguyên tố, đồng thời trao đổi và học tập kinh nghiệm ở Quý Thầy
Cô ở Tổ Tin học
I.4/ Đối tượng nghiên cứu
Trong nghiên cứu này, các học sinh được chọn là các em học lớp chuyên Tin học khối 10, 11, 12 thuộc một trường THPT Chuyên Tiền Giang và một số giáo viên đứng lớp dạy tin học ở trường THPT đó
I.5/ Các phương pháp nghiên cứu
* Phương pháp suy luận, tổng hợp: kết hợp từ nhiều nguồn tài liệu tham khảo của các tác giả và tra cứu trên mạng internet với các đề thi Học sinh Giỏi rút ra những kinh nghiệm, hệ thống lại kiến thức, mở ra các hướng mới
Trang 3* Phương pháp trò chuyện – phỏng vấn: trao đổi tâm tình với nhiều học sinh giỏi để nắm tình hình trong việc giải các bài toán tin về số
* Phương pháp khảo sát: bản thân được tham gia giảng dạy các lớp, đội tuyển HSG, các kỳ tập huấn, ra đề; tham khảo đồng nghiệp, quý Thầy Cô đã giảng dạy đội tuyển nhiều năm nên có nắm được tình hình sử dụng các phương pháp làm bài của các em học sinh
* Phương pháp phân tích lý luận: phân tích giúp học sinh nắm thật rõ bản chất vấn đề, lựa chọn được phương pháp giải cho phù hợp
Trang 4II PHẦN NỘI DUNG
II.1/ Lịch sử của vấn đề nghiên cứu
Trong những năm liên tiếp dạy bồi dưỡng HSG lớp 10, 11, 12 và đội tuyển thi HSG cấp Tỉnh, cấp Quốc Gia môn Tin học và bản thân tôi được tham dự lớp “BỒI DƯỠNG TẬP HUẤN GIẢNG DẠY CHUYÊN ĐỀ MÔN CHUYÊN TIN HỌC THPT” nhiều năm do Bộ GD&ĐT tổ chức Tôi nhận thấy kiến thức về Tin học của mình được nâng lên rõ rệt Các bài giảng của các Thầy NGUYỄN THANH TÙNG, Thầy ĐỖ ĐỨC ĐÔNG, Thầy LÊ MINH HOÀNG, cũng như tham khảo ý kiến các đồng nghiệp chuyên dạy bồi dưỡng đội tuyển ở các Tỉnh bạn, ở các trường THPT Chuyên, tôi rút ra một điều là “KIẾN THỨC TOÁN HỌC RẤT QUAN TRỌNG DẠY LẬP TRÌNH TRONG TIN HỌC” Được sự động viên khuyến khích của quý Thầy Cô trong tổ, cũng như thầy LÊ NGỌC LINH, tôi mạnh dạng tiếp tục chọn viết phần hai cho đề tài này là “Số nguyên tố”;
II.2/ Cơ sở lý luận của đề tài
Kết hợp bài giảng và các tài liệu tham khảo để phân tích, tổng hợp, hệ thống
II.3/ Thực trạng của vấn đề nghiên cứu
Đa số học sinh chuyên tin rất ngại, sợ khi giải các bài toán tin về số có ứng dụng toán; rất lúng túng trong quá trình phân tích, tổ chức dữ liệu, thuật toán để tìm
ra bản chất và vận dụng kiến thức một cách thích hợp
II.4/ Nội dung nghiên cứu và kết quả nghiên cứu
A/ NỘI DUNG NGHIÊN CỨU
A.1) Số nguyên tố
A.1.1) Kiến thức cơ bản trong toán học
A.1.1.1) Định nghĩa số nguyên tố
Một số nguyên p (p > 1) là số nguyên tố nếu p có đúng hai ước số 1 và p Một
số nguyên lớn hơn 1 mà không là số nguyên tố được gọi là hợp số
Ví dụ: các số nguyên tố là: 2, 3, 5, 7, 11, 13, 17,…
A.1.1.2) Các định lí cơ bản về số nguyên tố
Trang 5 Bổ đề 1: Mọi số nguyên lớn hơn 1 đều chia hết cho ít nhất một số nguyên
tố
Chứng minh bổ đề 1: Ta dể dàng chứng minh bằng phương pháp quy nạp Bổ đề 2: Mọi hợp số có ước thực sự nhỏ hơn hoặc bằng căn bậc hai của nó
(ước thực sự là ước khác 1 và khác chính nó)
Chứng minh bổ đề 2: Vì n là hợp số nên ta có: n = a.b với 1 < a, b < n
Nếu đồng thời a, b > n thì n = n n < a.b = n (mâu thuẩn)
Vậy có ít nhất một trong hai số a, b phải nhỏ hơn hoặc bằng n
Nhận xét: từ bổ đề trên ta có nhận xét sau:
Mỗi hợp số phải có ước nguyên tố nhỏ hơn hoặc bằng căn bậc hai của nó
Định lý (Định lý Fecma nhỏ): Nếu p là số nguyên tố và a là số tự nhiên thì
a p mod p = a
Từ những lý thuyết toán cơ sở trên, ta có thể ứng dụng chúng vào các giải thuật kiểm tra số nguyên tố trong tin học
A.1.2) Giải thuật kiểm tra số nguyên tố trong tin học:
Bài toán: Kiểm tra số nguyên dương n có phải là số nguyên tố không?
Ý tưởng: Nếu n > 1 không chia hết cho số nguyên nào trong tất cả các số k
Giải thuật 1: (Pascal)
Function is_prime(n: longint): boolean;
Var k: longint;
Begin
Trang 6if n = 1 then exit (false);
Nhận xét: Hàm is_prime(n) tiến hành lần lượt kiểm tra số k trên đoạn [2, n]
Để cải tiến, ta giảm số lần kiểm tra, ta kiểm tra xem có tồn tại một số nguyên
tố k (2 k n ) mà k là ước của n thì n không phải là số nguyên tố, ngược lại n là nguyên tố Thay vì kiểm tra k là số nguyên tố trên đoạn [2, n] ta kiểm
tra số k có tính chất giống với tính chất của số nguyên tố trong đoạn [2, n]:
Tc1 Trừ số 2 và các số nguyên tố là số lẻ
Tc2 Trừ số 2 và 3, các số nguyên tố có dạng 6k 1 (vì các số dạng
6k2;6k3 chia hết cho 2;3)
Giải thuật 2: (Pascal)
Function is_prime2(n: longint): boolean;
Var k, sqrt_n: longint;
Begin
if (n = 2) or (n = 3) then exit (true);
if (n = 1) or (n mod 2 = 0) or (n mod 3 = 0) then exit (false);
Trang 7Nhận xét: Với hai giải thuật trên, ta có thể chạy chương trình với n = 106, khi
n lớn (khoảng 107 trở đi) chương trình chạy chậm Muốn kiểm tra những số nguyên lớn có nguyên tố, người ta chuyển sang hướng kiểm tra xác suất Có nhiều thuật toán xây dựng theo hướng này: dựa vào định lý Fermat nhỏ có kiểm tra Fermat và kiểm tra Miller-Rabin là tiêu biểu
Giải thuật 3: Kiểm tra nguyên tố dùng định lý Fecmat nhỏ
Ý tưởng:
Lặp k lần {
Chọn giá trị ngẫu nhiên a, 2 ≤ a ≤ p-1
Nếu ap-1 1 (mod p) thì tăng biến đếm c (số lần thừa nhận p có thể là
nguyên tố), ngược lại thì p là hợp số và thoát
}
Nếu tỉ số c/k > xacsuat thì có thể chấp nhận p là nguyên tố (với xác suất sai nhỏ)
Giải thuật:
function is_prime3(p : int64): boolean;
var test, dem, a : longint;
Trang 10Bài toán: In ra các số nguyên tố trong [1; n]
Ý tưởng: Với bài toán này, ta có thể thử lần lượt các số m trong đoạn [1; n], rồi kiểm tra tính nguyên tố của m dựa vào các giải thuật trên
Trang 11End;
Nhận xét: Cách này đơn giản nhưng chạy chậm; để cải tiến, ta sử dụng tính
chất của số nguyên tố để loại bỏ trước những số không phải là nguyên tố và không cần kiểm tra các số này; ta sử dụng sàn nguyên tố như sàn Eratosthene
Ý tưởng: (sàn nguyên tố Eratosthene)
Trước tiên xóa bỏ số 1 ra khỏi tập các số nguyên tố; Số tiếp theo số 1 là số 2, là
số nguyên tố, xóa tất cả các bội của 2 ra khỏi bảng Số đầu tiên không bị xóa sau số
2 (số 3) là số nguyên tố, xóa bội của 3,… Thuật toán tiếp tục cho đến khi gặp số nguyên tố lớn hơn n thì dừng lại Tất cả các số chưa bị xóa là số nguyên tố
Trang 12A.2) Một số bài tập áp dụng
Bài 1: Nhập một mảng 2 chiều m dòng, n cột từ file BANGSO.TXT Cấu trúc file như sau: dòng đầu là 2 số m và n, cách nhau bằng dấu cách, m dòng sau, mỗi dòng n số nguyên
Hãy in ra những số là số nguyên tố của mảng
Trang 13if k mod i = 0 then exit;
Bài 2: (Sinh số nguyên tố) Tạo ra mọi số nguyên tố giữa hai số đã cho
Input Tệp SINH_NT.INP Dòng đầu tiên ghi số t là số test (t ≤ 10) Trong mỗi
t dòng tiếp theo là hai số m và n (1 ≤ m ≤ n ≤ 109, n-m ≤ 105) cách nhau một dấu cách
Output. Tệp SINH_NT.OUT với mỗi test ghi mọi số nguyên tố p sao cho
m ≤ p ≤ n, mỗi số một dòng, mỗi test cách nhau một dòng trống
Trang 14start, stop : tdatetime;
while (y>0) do begin
if (y mod 2=1) then z := (z* (x mod n)) mod n;
Trang 15function prime(n : int64): boolean;
var dem, r, a, x : int64; k: longint;
Trang 16Bài 3: (Kiểm tra tính nguyên tố) Số đó có là số nguyên tố hay không?
Input Tệp YESNO.INP Dòng đầu tiên ghi số t là số các test, sau đó là t test
(t≤500): mỗi test trên một dòng chứa một số nguyên N (2 ≤ N < 231)
Output Tệp YESNO.OUT với mỗi test, ghi trên một dòng một xâu “YES” nếu
số đã cho là nguyên tố, hoặc xâu “NO” trong trường hợp ngược lại
Trang 17while (y>0) do begin
if (y mod 2 =1) then z := ((z mod n)* (x mod n)) mod n;
function prime(n : int64): boolean;
var dem, r, a, x : int64; k: longint;
begin
Trang 19Input Tệp nt_vong.inp gồm một dòng ghi hai số a và b
Output Tệp nt_vong.out ghi số lượng số nguyên tố vòng trong [a; b]
uses crt;
const fi = 'nt_vong.inp';
fo = 'nt_vong.out';
var a, b, n, x : longint;
procedure chuyen(var s: string);
var code : integer;
begin
s := copy(s,2,length(s))+s[1];
end;
function prime(a: int64): boolean;
var i, sqrt_a: longint;
begin
if ((a=2) or (a=3)) then exit(true);
if ((a<2) or (a mod 2=0) or (a mod 3=0)) then exit(false);
sqrt_a := trunc(sqrt(a));
i:=5;
while (i<=sqrt_a) do begin
Trang 20if ((a mod i = 0) or (a mod (i+2)=0)) then exit(false) else
inc(i,6);
end;
exit(true);
end;
function vong(x : longint): boolean;
var i, l : integer; s: string; code: integer;
Bài 5: Cho số tự nhiên n 480.000 Hãy phân tích n! ra tích của các thừa số
nguyên tố theo trật tự tăng dần Thí dụ, 13! = 210.35.52.7.11.13 Kết quả hiển thị
Trang 21dưới dạng các dòng, mỗi dòng một 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 Thí dụ trên cho ta kết quả hiển thị như sau
Nhận xét: Cho số tự nhiên N và một số nguyên tố p Khi đó,
Nếu viết dãy thừa số 1, 2, , N vào một bảng có p cột thì ta thấy có n1 = N div
p dòng chứa p, 2p, ,n 1 p (ở cột cuối cùng) Nhóm các phần tử này lại ta được,
1p.2p n 1 p = (1.2 n 1 ).pn1 Thực hiện tương tự với tích 1.2 n1 ta thu được n2 =
n1 div p dòng chứa p, 2p, ,n 2 p Từ đây ta suy ra lũy thừa k của p, p k trong dạng
phân tích của N! sẽ là k = n1+n2+ +nv, trong đó ni = ni-1 div p, n1 = N div p, nv = 0, i
= 2 v Hàm tính lũy thừa của p trong dạng phân tích của N! bằng các phép chia liên
tiếp khi đó sẽ như sau,
function Power(n,p: longint): byte;
Ta dùng hàm NextPrime để sinh lần lượt các số nguyên tố p trong khoảng 2 N
và tính Power(N,p) Nếu giá trị này lớn hơn 0 thì ta hiển thị kết quả
Trang 22procedure Fac(n: longint);
const bl = #32; { Dau cach }
var p: longint; k: byte;
Hàm IsPrime(p) kiểm tra p có phải là số nguyên tố hay không bằng cách xét
xem trong khoảng từ 2 đến p có ước nào không
function IsPrime(p: longint): Boolean;
Hàm NextPrime(p) sinh số nguyên tố sát sau p bằng cách duyệt tuần tự các số
lẻ sau p là p+2k nếu p lẻ và (p-1) + 2k, nếu p chẵn
function NextPrime(p: longint): longint;
Trang 23Bài 6: Số nguyên tố cùng độ cao
Độ cao của một số tự nhiên là tổng các chữ số của số đó Với mỗi cặp số tự
nhiên n và h cho trước hãy liệt kê các số nguyên tố không vượt quá n và có độ cao h,
Thuật toán liệt kê các số nguyên tố độ cao h trong khoảng 1 n
1 Gọi thủ tục Sang(n) (do Eratosthenes)
xác định các số nguyên tố trong khoảng 1 n
Trang 24và đánh dấu vào mảng byte p: p[i] = 0 khi và chỉ khi i là số nguyên tố
2 Duyệt lại các số nguyên tố i trong danh sách p, tính độ cao của số i
Nếu Height(i) = h thì ghi nhận
3 end
Để tính độ cao của số i ta tách dần các chữ số hàng đơn của i bằng phép chia dư
cho 10 rồi cộng dồn vào một biến tổng
procedure Sang(n: longint);
var i,j: longint;
function Height(x: longint): integer;
var sum : integer;
Trang 25Doc; Sang(n); Ghi;
writeln(nl,' Fini'); readln;
END
Trang 26A.3) Một số bài tập đề nghị
Bài 1: Tìm tất cả các số nguyên tố có 2, 3, 4, 5 chữ số
Bài 2: Số thân thiện
Tìm tất cả các số tự nhiên hai chữ số mà khi đảo trật tự của hai chữ số đó sẽ thu được một số nguyên tố cùng nhau với số đã cho
Số nguyên tố từ chuỗi là những số ghép từ một hoặc nhiều số lấy ra được từ
chuỗi kết hợp lại thành
Ví dụ: Từ chuỗi anh1fku13djdndkfk ta được các số nguyên tố: 13, 113, 131
Từ chuỗi dadh3dklk7slkkjhf ta được các số nguyên tố: 3, 7, 37, 73
Dữ liệu vào: từ tập tin văn bản SNT.INP
Gồm N dòng, mỗi dòng là 1 chuỗi các kí tự, kí số
Kết quả: Đưa ra tập tin văn bản SNT.OUT
Gồm N dòng, mỗi dòng là 1 số nguyên, là số các số nguyên tố từ chuỗi
Trang 27Như vậy, Tin học đã sử dụng Toán học rất nhiều Đặc biệt số nguyên tố và xử
lí trên các số nguyên tố mà dựa vào các định lý, bổ đề trong toán học mà Tin học đã xây dựng được những thuật toán, giải thuật rất hữu dụng, ngày nay việc kiểm tra số nguyên tố không còn là vấn đề khó khăn như trước đây chưa có sử dụng tin học
B/ KẾT QUẢ NGHIÊN CỨU
Qua quá trình nghiên cứu và vận dụng đề tài chuyên đề “ỨNG DỤNG LÝ
THUYẾT TOÁN ĐỂ GIẢI CÁC BÀI TOÁN TIN” phần 2 - số nguyên tố, tôi nhận
thấy vấn đề này giúp ích rất nhiều cho học sinh chuyên tin học trong việc học, giúp các em không còn “ngán ngại” chuyên đề này nữa, các em đã hiểu và vận dụng khá tốt những phần liên quan đến toán học cũng như tin học (như thuật toán kiểm tra, sàn nguyên tố, xử lí số nguyên tố lớn,…); một số em đã bước đầu sáng tạo được những bài toán mới (tuy là những bài toán còn “đơn giản”) Riêng bản thân tôi sẽ tiếp tục nghiên cứu sâu hơn nữa về chuyên đề này hy vọng sẽ “làm rõ hơn nữa” để học sinh chuyên tin thích học và đạt nhiều thành tích hơn nữa
Trang 28III.2/Tài liệu tham khảo
1 Nguyễn Xuân Huy, 2008, tuyển các bài toán tin nâng cao cho học sinh và sinh viên giỏi “Sáng tạo trong thuật toán và lập trình”, NXB Giáo dục, tập 1, tập 2,
tập 3
2 Hồ Sĩ Đàm, Đỗ Đức Đông, Lê Minh Hoàng, Nguyễn Thanh Hùng, 2009, “Tài liệu giáo khoa chuyên tin”, NXB Giáo dục, quyển 1, quyển 2, quyển 3
3 Donald E Knuth, The Art of computer programming
4 Kenneth H Rosen, Toán học rời rạc ứng dụng trong tin học, NXB Giáo dục,
2007, người dịch Phạm Văn Thiều và Đặng Hữu Thịnh