I. PHẦN MỞ ĐẦU 1. Lý do chọn sáng kiến Trong giai đoạn hiện nay máy tính điện tử đã nhanh chóng thâm nhập vào mọi lĩnh vực sản xuất, kinh tế và đời sống xã hội. Chính vì vậy việc dạy tin học ở trường phổ thông có vai trò quan trọng vì việc giáo dục đó là nhằm chuẩn bị cho thế hệ trẻ Việt Nam về mặt tri thức, kỹ năng, về mặt năng lực, trí tuệ và các phẩm chất cần thiết giúp học sinh thích ứng với thời đại 4.0. Giúp cho học sinh sau khi tốt nghiệp nắm được một số yếu tố cơ bản của tin học. Xét về mặt năng lực, trí tuệ: Giúp phát triển nhiều phương thức, tư duy liên hệ mật thiết với việc sử dụng kỹ thuật xử lý thông tin như: tư duy thuật toán, tư duy điều khiển, tư duy ngôn ngữ,... Ðồng thời hình thành và phát triển năng lực hoạt động trí tuệ nói chung như phân tích, tổng hợp, khái quát hóa, trừu tượng hóa,... Để xử lí thông tin tốt và để nâng cao năng lực học tập cho học sinh thì việc học ngôn ngữ lập trình pascal là một nhiệm vụ hết sức quan trọng.
Trang 1I PHẦN MỞ ĐẦU
1 Lý do chọn sáng kiến
Trong giai đoạn hiện nay máy tính điện tử đã nhanh chóng thâm nhập vào mọi lĩnh vực sản xuất, kinh tế và đời sống xã hội Chính vì vậy việc dạy tin học
ở trường phổ thông có vai trò quan trọng vì việc giáo dục đó là nhằm chuẩn bị cho thế hệ trẻ Việt Nam về mặt tri thức, kỹ năng, về mặt năng lực, trí tuệ và các phẩm chất cần thiết giúp học sinh thích ứng với thời đại 4.0 Giúp cho học sinh sau khi tốt nghiệp nắm được một số yếu tố cơ bản của tin học Xét về mặt năng lực, trí tuệ: Giúp phát triển nhiều phương thức, tư duy liên hệ mật thiết với việc
sử dụng kỹ thuật xử lý thông tin như: tư duy thuật toán, tư duy điều khiển, tư duy ngôn ngữ, Ðồng thời hình thành và phát triển năng lực hoạt động trí tuệ nói chung như phân tích, tổng hợp, khái quát hóa, trừu tượng hóa, Để xử lí thông tin tốt và để nâng cao năng lực học tập cho học sinh thì việc học ngôn ngữ lập trình pascal là một nhiệm vụ hết sức quan trọng
Tuy nhiên học sinh gặp phải rất nhiều khó khăn khi lập trình Pascal, vì học sinh chưa chủ động rèn luyện cách trình bày thuật toán, các lập luận, những kiến thức được áp dụng trong quá trình lập trình nên dẫn đến thụ động, rập khuôn, thiếu tính sáng tạo
Để tiếp tục hoàn chỉnh chuyên đề bồi dưỡng HSG Tin học “Ứ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 chọn viết sáng kiến “Ứng dụng lý thuyết toán để giải các bài toán tin”
2 Phạm vi và đối tượng của sáng kiến
2.1 Phạm vi
- Phạm vi nghiên cứu tại trường PTDTNT Lục Nam trong thời gian từ năm 2021 đến nay
2.2 Đối tượng
- Học sinh trường PT DTNT huyện Lục Nam
II PHẦN NỘI DUNG
1 Thực trạng của vấn đề mà sáng kiến cần giải quyết
1.1 Ưu điểm
- Được sự quan tâm của Ban giám hiệu nhà trường, tổ chuyên môn
- Tập thể nhà trường đoàn kết và thống nhất trong việc thực hiện nhiệm vụ Đội ngũ giáo viên đủ về số lượng Giáo viên nhiệt huyết, có tinh thần trách nhiệm với học sinh
- Giáo viên và học sinh và được hưởng chính sách ưu đãi của Đảng và Nhà nước nên yên tâm trong công tác giảng dạy, học tập
Trang 2- Học sinh ở nội trú nên thuận lợi cho việc bồi dưỡng CLB.
1.2 Hạn chế và nguyên nhân hạn chế
* Giáo viên:
- Sự quan tâm đổi mới phương pháp của giáo viên chưa đồng đều, chưa thực sự đi vào chiều sâu; đôi khi còn qua loa, hình thức Việc thực hiện tiết dạy của giáo viên vẫn chưa thật sự hấp dẫn, lôi cuốn học sinh; còn nhiều học sinh thụ động trong việc tiếp thu kiến thức dẫn đến giờ học kém hiệu quả
+ Giáo viên còn ngại đổi mới, còn hạn chế trong phương pháp dạy học, sử dụng đồ dùng dạy học chưa thường xuyên
+ Giáo viên trực ban chưa thực sự quan tâm sâu sát, chưa gần gũi nắm bắt tâm tư tình cảm và kịp thời chia sẻ với học sinh những khó khăn, bất ổn trong cuộc sống
- Tâm lý học sinh đa số coi Tin học là môn tự chọnnên chưa chú ý nhiều trong quá trình học tập
- Học sinh sống trong thời đại công nghệ có quá nhiều cám dỗ dẫn đến lơ
là trong học tập, không đặt mục tiêu học tập lên hàng đầu
* Học sinh:
- Trên 95% học sinh là con em dân tộc thiểu số và 100% học sinh đang sinh sống tại vùng đặc biệt khó khăn của huyện; 100% học sinh trong CLB Tin học trẻ là người dân tộc thiểu số nên trình độ nhận thức của các em còn nhiều hạn chế
- Một số học sinh còn lười học, ham chơi, vô cảm với kết quả học tập, một
bộ phận học sinh không có động lực phấn đấu học lên cao để trở thành học sinh khá giỏi
- Một số học sinh chưa thực sự đam mê, thiếu tập trung
- Học sinh bị phân tán bởi một số câu lạc bộ văn hóa và thể thao khác
2 Các giải pháp thực hiện
2.1 Số nguyên tố
2.1.1 Kiến thức cơ bản trong toán học
* Đị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ố là 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,…
* Các định lí cơ bản về số nguyên tố
- 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.
Trang 3- 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
2.1.2 Giải pháp 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 chạy từ 2 đến √n thì n là số nguyên tố.
- Câu hỏi đầu tiên học sinh sẽ hỏi các thầy cô là: “Tại sao chỉ xét mọi k chạy từ 2 đến √n ”?
- Thật vậy, theo bổ đề 2, nếu n (n > 1) không phải là số nguyên tố, ta có:
n=k1k2 mà 2≤k1≤k2≤n-1
Vì k12=k1k1≤k1k2=n nên k1≤√n
* Giải pháp 1 : (Pascal)
Function is_prime(n: longint): boolean;
Var k: longint;
Begin
if n = 1 then exit (false);
for k := 2 to trunc(sqrt(n)) do
if (n mod k = 0) then exit (false);
exit (true);
End;
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à số 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]:
Trang 4- Tc1 Trừ số 2 và các số nguyên tố là số lẻ
- Tc2 Trừ số 2 và s ố 3, các số nguyên tố có dạng 6k ± 1 (vì các số dạng 6k ± 2; 6k ± 3 chia hết cho 2;3)
* Giải pháp 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); sqrt_n := trunc(sqrt(n));
k := -1;
Repeat
inc(k,6);
if (n mod k = 0) or (n mod (k+2) = 0) then break;
Until k > sqrt_n;
exit (k > sqrt_n));
End;
Nhận xét: Với hai giải pháp 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 pháp 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;
Begin
Trang 5if (p=2) or (p=3) then exit(true);
if (p<2) or (p mod 2=0) or (p mod 3=0) then exit(false);
randomize; dem := 0;
for test:=1 to ntest do
begin
a := random(p-2) + 2;
if luythua(a,p-1,p) <> 1 then exit(false) else inc(dem);
if (dem/ntest> 0.6) then exit(true);
end;
exit(false);
end;
Trong giải thuật prime_3 trên, ta có sử dụng hàm luythua(x,y,n) Hàm luythua(x,y,n) được viết như sau:
function luythua(x,y,n: int64): int64;
var z1: longint;
begin
if y=0 then exit(1)
else begin
z := luythua(x, y div 2, n);
z1 := ((z mod n)*(z mod n)) mod n;
if (y mod 2 = 1) then
z1:= ((x mod n)*(z1 mod n)) mod n;
if z1 > n then z1:= z1 mod n;
exit(z1);
end;
end;
* Giải pháp 4 : Kiểm tra nguyên tố Miller-Rabin
- Ý tưởng :
{ Phân tích số lẻ n: n-1=d.2s (d lẻ)
Lặp: ntest lần {
Chọn a thuộc{2, ,n-1};
Trang 6Tính x = a d (mod n);
Nếu (x=1) or (x=n-1) về đầu lặp;
k=1;
Lặp: Trong khi k<s {
x = x 2 (mod n);
Nếu x =1 then n là hợp số, kết thúc; Nếu x =n-1: Thoát lặp trong;
k = k+1;
}
Nếu x <> n-1: n là hợp số, kết thúc;
}
n là nguyên tố
}
Giải thuật :
function is_prime4(n : int64): boolean;
var dem, r, a, x : int64; k: longint;
begin
if n=2 then exit(true);
if (n<2) or (n mod 2=0) then exit(false);
phantich(n-1,d,s);
randomize;
for k:=1 to ntest do
begin
a := random(n-2)+2;
x := luythua(a,d,n);
if (x=1) or (x=n-1) then continue;
r := 1;
while r < s do
begin
x:= luythua(x,2,n);
if x=1 then exit(false);
if x=n-1 then break;
Trang 7end;
if x <> n-1 then exit(false);
end;
exit(true);
end;
2.2 Sàn số nguyên tố
- Bà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.
- Thuật toán :
Procedure generate(N: longint);
Var m: longint;
Begin
For m:=2 to N do
If is_prime(m) then writeln(m);
End;
- 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ị xoá là
số nguyên tố
- Thuật toán
Procedure Eratosthene(N: Longint);
Const Max = 1000000;
Var i, j : longint;
prime: array[1 Max] of byte;
Begin
Fillchar(prime, sizeof(prime),0);
For i:=2 to trunc(sqrt(N)) do
If prime[i] = 0 then
Trang 8j := i*i;
While j <= N do
begin
Prime[j] := 1;
j := j + i;
end;
End;
For i:=2 to N do
If prime[i] = 0 then writeln(i);
End;
2.3 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
Chương trình:
var m,n : integer;
a : array[1 100,1 100] of integer;
procedure nhap;
var f : text;
i, j : integer;
begin
assign(f,'BANGSO.TXT'); reset(f); readln(f,m,n);
for i := 1 to m do
for j := 1 to n do read(f,a[i,j]);
close(f);
end;
function ngto(k : integer): boolean;
var i : integer;
begin
ngto := false;
if k < 2 then exit;
Trang 9for i := 2 to trunc(sqrt(k)) do
if k mod i = 0 then exit; ngto := true;
end;
procedure inngto;
var i,j : integer;
begin
writeln('Cac phan tu nguyen to cua mang:');
for i := 1 to m do
for j := 1 to n do
if ngto(a[i,j]) then write(a[i,j],' ');
writeln;
end;
BEGIN
nhap; inngto;
END
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
uses sysutils;
const ntest = 10;
fi = 'sinh_nt.inp'; fo = 'sinh_nt.out';
var m, n, p, d, s : int64;
i, t : integer; f,g : text;
Start, stop : tdatetime;
procedure phantich(x: int64; var d, s : int64);
begin
s := 0; d:=1;
while (x mod 2 =0) do
begin
x := x div 2; inc(s);
Trang 10d := x; end;
function exponent1(x,y,n: int64): int64;
var z : int64;
begin
z := 1;
while (y>0) do
begin
if (y mod 2=1) then z := (z* (x mod n)) mod n;
x := (x*x) mod n;
y := y div 2;
end;
exit(z);
end;
function exponent(x,y,n: int64): int64;
var z, z1 : int64;
begin
if y=0 then exit(1);
z:= exponent(x, y div 2,n);
z := z*z mod n;
if (y mod 2=1) then
z := x*z mod n;
if z>n then z := z mod n;
exit(z);
end;
function prime(n : int64): boolean;
var dem, r, a, x : int64; k: longint;
begin
if n=2 then exit(true);
if (n<2) or (n mod 2=0) then exit(false);
phantich(n-1,d,s);
randomize;
for k:=1 to ntest do
Trang 11a := random(n-2)+2;
x := exponent1(a,d,n);
if (x=1) or (x=n-1) then continue;
r := 1;
while r<s do
begin
x:= exponent1(x,2,n);
if x=1 then exit(false);
if x=n-1 then break; inc(r);
end;
if x<>n-1 then exit(false);
end;
exit(true);
end;
BEGIN
assign(g,fo); rewrite(g); assign(f,fi); reset(f); readln(f,t);
start := now;
for i:=1 to t do
begin
readln(f,m,n); p:=m;
while p<=n do
begin
if prime(p) then writeln(g,p);
p := p+1;
end;
writeln(g);
end;
close(f); close(g); stop := now;
writeln('Miller-Rabin, Time: ',(stop-start)*3600*24:0:5);
readln;
END
Bài
3 : (Kiểm tra tính nguyên tố) Số đó có là số nguyên tố hay không?
Trang 12Input 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
uses sysutils;
const ntest = 10;
fi = 'yesno.inp'; fo = 'yesno.out';
var n, d, s : int64;
i,t : integer;
start, stop : tdatetime;
f,g : text;
procedure phantich(x: int64; var d, s : int64);
begin
s := 0; d:=1;
while (x mod 2 =0) do
begin
x := x div 2; inc(s);
end;
d := x;
end;
function luythua(x,y,n: int64): int64;
var z : int64;
begin
z := 1;
while (y>0) do
begin
if (y mod 2 =1) then z := ((z mod n)* (x mod n)) mod n;
y := y div 2;
x := ((x mod n)*(x mod n)) mod n;
end;
exit(z);
end;
function prime(n : int64): boolean;
Trang 13var dem, r, a, x : int64; k: longint;
begin
If n=2 then exit(true);
if (n<2) or (n mod 2=0) then exit(false);
phantich(n-1,d,s);
randomize;
for k:=1 to ntest do
begin
a := random(n-2)+2;
x := luythua(a,d,n);
if (x=1) or (x=n-1) then continue;
r := 1;
while r<s do
begin
x:= luythua(x,2,n);
if x=1 then exit(false);
if x=n-1 then break; inc(r);
end;
if x<>n-1 then exit(false);
end;
exit(true);
end;
BEGIN
assign(g,fo); rewrite(g); assign(f,fi); reset(f); readln(f,t);
start := now;
for i:=1 to t do
begin
readln(f,n);
if prime(n) then writeln(g,'YES ') else writeln(g,'NO');
end;
close(f); close(g); stop := now;
writeln('Miller-Rabin, Time: ',(stop-start)*3600*24:0:5);
Trang 14END
Bài
4 : (Số nguyên tố vòng) số 993319 là nguyên tố vòng vì các số
993319, 933199, 331999, 319993, 199933, 999331, đều là số nguyên tố
Cho trước hai số nguyên dương a và b Tìm xem trong đoạn [a;b] có bao nhiêu số nguyên tố vòng Hạn chế: a<b≤106
Input 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
If ((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;
begin