SỞ GIÁO DỤC VÀ ĐÀO TẠO NINH BÌNH TRƯỜNG THPT NHO QUAN A SÁNG KIẾN “MỘT SỐ DẠNG THUẬT TOÁN CƠ BẢN VÀ ÁP DỤNG GIẢI BÀI TOÁN TRONG KỲ THI CHỌN HỌC SINH GIỎI THPT CẤP TỈNH” Tác giả: Nguyễn
Trang 1SỞ GIÁO DỤC VÀ ĐÀO TẠO NINH BÌNH
TRƯỜNG THPT NHO QUAN A
SÁNG KIẾN “MỘT SỐ DẠNG THUẬT TOÁN CƠ BẢN VÀ ÁP DỤNG GIẢI BÀI TOÁN TRONG KỲ THI CHỌN HỌC SINH
GIỎI THPT CẤP TỈNH”
Tác giả: Nguyễn Thị Quỳnh Nga
Chức vụ: Giáo viên Đơn vị công tác: Trường THPT Nho Quan A
Ninh Bình, tháng 5 năm 2022
Trang 2MỤC LỤC
PHẦN 1: ĐẶT VẤN ĐỀ……… 3
1.1 Lý do chọn đề tài 3
1.2 Mục tiêu của đề tài 3
1.3 Lĩnh vực áp dụng 4
1.4 Phương pháp nghiên cứu 4
PHẦN 2: GIẢI QUYẾT VẤN ĐỀ 5
2.1 Cơ sở lý luận 5
2.2 Thực trạng vấn đề trước khi nghiên cứu 5
2.3 Biện pháp thực hiện giải quyết vấn đề 6
2.3.1 Thuật toán về số……… 6
2.3.2 Thuật toán về vòng lặp……….16
2.3.3 Các bài toán tham khảo………17
2.4 Hiệu quả của sáng kiến kinh nghiệm ………30
2.5 Điều kiện và khả năng áp dụng ………31
2.5.1 Trước khi áp dụng……….31
2.5.2 Sau khi áp dụng……….31
PHẦN 3: KẾT LUẬN ………33
3.1.Kết luận.……….33
3.2 Một số kiến nghị.……….33
PHẦN 4: TÀI LIỆU THAM KHẢO………35
Trang 3PHẦN 1: ĐẶT VẤN ĐỀ
1.1 Lý do chọn đề tài
Bồi dưỡng học sinh giỏi là công việc quan trọng và được quan tâm trong nhàtrường, nó giúp nhà trường phát hiện ra các hạt giống tốt để bồi dưỡng trở thành nhân tàitương lai cho đất nước.Việc bồi dưỡng học sinh giỏi cũng là một trong những nhiệm vụvất vả, khó khăn và thử thách đối với mỗi giáo viên
Khi lập trình giải quyết một bài toán theo tôi vấn đề mà được các em học sinh quantâm nhất đó là lựa chọn và sử dụng thuật toán nào cho bài toán với một tập hợp các kiếnthức các em đã được học Không phải lúc nào và với lớp bài toán nào chúng ta cũng cómột cách làm như nhau được mà đỏi phải sử dụng các kiến thức linh hoạt Chúng ta cầnđánh giá được sự tác động của các giải thuật áp dụng vào trong bài toán của mình ở cácmức độ khác nhau và từ đó định hướng tìm ra giải thuật phù hợp nhất
Thi học sinh giỏi môn tin học thật sự là khó, nó đòi hỏi các em phải có kiến thứcvững và kỹ năng tốt về lập trình Do đó, trong kỳ thi học sinh giỏi tỉnh, các thí sinh dự thithường không lấy được điểm trọn vẹn ở câu 1 liên quan đến một số thuật toán cơ bản.Vậy làm thế nào để các em trong đội tuyển lĩnh hội tốt kiến thức phần khi tham gia ônluyện? Làm thế nào để bài thi đạt được kết quả tốt nhất? Từ những lý do đó, qua tìm tòi
và trao đổi với các đồng nghiệp, tôi đã quyết định chọn đề tài: “ Một số thuật toán cơ
bản và áp dụng giải bài toán trong kỳ thi chọn học sinh giỏi THPT cấp tỉnh”.
1.2 Mục tiêu của đề tài
-Nâng cao chất lượng dạy và học bộ môn tin học
-Giúp học sinh ôn luyên trong đội tuyển biết được những kiến thức cơ sở
-Khích lệ cổ vũ phong trào học tập của học sinh trong đội tuyển
-Tạo điều kiện thuận lợi cho những học sinh có năng lực, có niềm đam mê, có sáng tạotrong học tập bộ môn
-Giúp học sinh nâng cao kiến thức, kỹ năng tìm ra phương pháp học để học sinh yêu thíchhọc môn Tin hơn nữa
-Giúp cho bản thân người dạy cũng như đồng nghiệp bổ sung vào phương pháp dạy học,
có thêm một tư liệu tham khảo hữu ích trong quá trình dạy bồi dưỡng học sinh giỏi.-Tăng cường trao đổi học tập kinh nghiệm từ đồng nghiệp nhằm nâng cao chuyên môn vàkhả năng tự học, tự đào tạo thực hiện phương châm học thường xuyên, học suốt đời
Trang 41.3 Lĩnh vực áp dụng
- Giáo viên tham gia giảng dạy và học sinh trong đội tuyển Tin học
- Các kiến thức, kỹ năng cơ bản cần thiết trong kì thi học sinh giỏi tỉnh
1.4 Phương pháp nghiên cứu
Để nghiên cứu đề tài này, tôi đã sử dụng một số nhóm phương pháp nghiên cứu sau:
- Thu thập, phân tích các tài liệu và thông tin liên quan tới đề tài
- Tìm hiểu các bài toán cơ bản và nâng cao trong phạm vi kiến thức ôn thi học sinh giỏitỉnh môn tin học
- Tham khảo, tìm kiếm các bài toán hay trên các Website và các tài liệu khác, đặc biệt làcác bài toán trong các đề thi học sinh giỏi của tỉnh ta và của các tỉnh khác Từ đó tổnghợp, thống kê những kiến thức cần thiết, những dạng bài tập cơ bản và nâng cao làmnguồn tư liệu tham khảo sau này
- Thống kê, phân tích số liệu về chất lượng thi học sinh giỏi môn Tin học để làm nổi bậttầm quan trọng của đề tài
Trang 5PHẦN 2: GIẢI QUYẾT VẤN ĐỀ 2.1 Cơ sở lý luận
- Đảng và Nhà nước đã vạch ra đường lối rất đúng đắn về chiến lược con người là “nâng cao dân trí, đào tạo nhân lực, bồi dưỡng nhân tài” Do đó, việc nâng cao chấtlượng dạy và học là mục tiêu trọng tâm của ngành giáo dục và đào tạo.Trong cáctrường học hiện nay, việc phát triển bồi dưỡng học sinh giỏi là nhiệm vụ mũi nhọn
- Chúng ta đang sống ở thế hệ thông tin vì thế công nghệ thông tin ngày càng được ứngdụng rộng rãi trong nhiều ngành then chốt, đặc biệt là ngành Giáo dục và Đào tạo
- Tin học là môn khoa học tự nhiên, nó là cơ sở, là nền tảng của nhiều lĩnh vực khoahọc Nhu cầu học tập, nâng cao kiến thức và say mê khám phá khoa học của học sinhngày càng nâng cao Vì vậy môn tin học ngày càng được nhiều em học sinh quan tâm,lựa chọn là môn học ưa thích và cần thiết cho mình Nếu học sinh thực hiện tốt việc lựachọn và cài đặt chương trình tối ưu khi giải các bài tập về dạng thuật toán cơ bản nóiriêng và các bài tập lập trình nói chung thì chất lượng học sinh giỏi sẽ được nâng cao
2.2 Thực trạng vấn đề trước khi nghiên cứu
Môn Tin học là môn học đặc thù có nhiều kiến thức khó như lập trình pascal ở lớp
11 (đây là kiến thức thi học sinh giỏi tỉnh môn Tin học) nhưng thường bị xem nhẹ, bị xem
là “môn phụ” Học sinh – phụ huynh chưa quan tâm đúng mực tới môn học nên việc lựa
chọn và bồi dưỡng học sinh giỏi là vô cùng khó khăn
Năm 2014 – 2015 tôi có phối hợp cùng một giáo viên khác tham gia công tác bồidưỡng học sinh giỏi tỉnh môn Tin học, cũng là năm đầu tiên tôi tham gia công tác bồidưỡng học sinh giỏi Việc dạy đội tuyển của tôi chủ yếu dựa trên những kiến thức cơ bảncủa sách giáo khoa, một số thuật toán thường gặp, chưa chú trọng nhiều đến cải tiếnchương trình tối ưu hơn để chương trình chạy nhanh hơn và chủ yếu là định hướng chohọc sinh tìm ra được thuật toán (cách làm) để chương trình cho ra được kết quả mà thôi.Chính vì vậy khi giải quyết các dạng bài toán cơ bản, học sinh và ngay cả giáo viênthường chỉ làm việc với các bộ input có dữ liệu nhỏ dễ nhìn thấy kết quả output và thườngkhông xét đến trường hợp input đặc biệt hay các input có dữ liệu lớn, và chỉ cần ra kếtquả là được Dẫn đến bị mất điểm nhiều điểm trong bài thi học sinh giỏi
Đối với thi học sinh giỏi, dù kết quả output của 2 thí sinh có giống hệt nhau với cùngmột bộ input, nhưng việc chênh lệch về thời gian khi lựa chọn thuật toán sẽ quyết định thísinh có thể thắng hay bại (yêu cầu thời gian xử lí chương trình không quá 1 giây/1 test)
Trang 6Trong các kì thi học sinh giỏi từ năm 2017 trở về trước, với cấu trúc đề 3 câu tươngứng với số điểm 6, 7, 7, trong đó bao giờ cũng có ít nhất 1 câu về dạng thuật toán cơ bản,hoặc từ năm 2018 đến nay, với cấu trúc đề 4 câu tương ứng với số điểm 4, 6, 4, 6, trong
đó có nhiều nhất 2 câu liên quan đến vấn đề này và không quá 60% các dữ liệu input lànhỏ vừa tầm thì việc thí sinh dù có làm hết cả 3 hay 4 câu trong đề thì nguy cơ khôngđược giải vẫn rất cao
Vì vậy, kết quả học sinh giỏi năm 2014- 2015 chưa được như mong muốn, có 3 emhọc sinh tham gia thi học sinh giỏi THPT cấp tỉnh nhưng không có em nào đạt giải (mặc
dù khi đi thi về có em rất phấn khởi vì nghĩ mình làm bài tốt Đúng vậy bài làm các emđều cho kết quả đúng trong khoảng thời gian cho phép nhỏ hơn 1 giây nhưng với bộ input
có dữ liệu nhỏ còn bộ input có dữ liệu lớn thì bài làm vẫn cho kết quả đúng nhưng thờigian chạy chương trình quá 1giây, nghĩa là bộ test có dữ liệu lớn các em bị mất điểm).Vấn đề đặt ra, là làm thế nào để lấy được điểm với các bộ input có dữ liệu lớn Muốnvậy cần phải lựa chọn và cài đặt được chương trình hiệu quả (tối ưu) Chương trình hiệuquả là chương trình giải quyết được những bộ input có dữ liệu lớn, chính xác, dung lượng
sử dụng bộ nhớ nhỏ, thời gian thực chương trình ngắn
2.3 Biện pháp thực hiện giải quyết vấn đề
2.3.1 Thuật toán về số
Bài toán liên quan đến ước số
a) Bài toán tính tổng các ước số của một số nguyên dương N
Ví dụ: N=20, kết quả = 42
+ TH1: nếu N≤ 106 một cách đơn giản ta có thể làm như sau:
Thuật toán: Liệt kê các ước và cộng chúng lại
Đoạn chương trình chính:
For u:=1 to N do
If N mod u =0 then T:=T+u;
//u: biến kiểm tra ước của N; T:dùng lưu tổng các ước
+ TH2: N≥ 106 lúc đó thuật toán trên không còn phù hợp ta phải sử dụng thuật toánkhác như sau:
Nếu n có phân tích thành thừa số nguyên tố: N= ai x bj x… x ck thì ta có:
1 1 1 1 1 1
Trang 8Giả sử nếu N tồn tại ước k1≤ N thì luôn tồn tại ước k2 ≥ N
Trong trường hợp: N không phải là số chính phương số ước k1= số ước k2 ngượclại có một ước k1=k2 Vì vậy để giải quyết bài toán trên chúng ta chỉ cần kiểm tra các ướcnhỏ hơn N và suy ra ước còn lại
Chương trình xử lý chính như sau:
for i:=2 to trunc(sqrt(n))+1 do
if n mod i=0 then
Trang 9TH1: nếu N≤ 106 một cách đơn giản ta có thể làm như sau:
Thuật toán: Liệt kê và đếm các ước
Đoạn chương trình chính
For u:=1 to N do
If N mod u =0 then inc(d); // d: kết quả TH2: nếu N≥ 106
Cách 1: Dùng phương pháp liệt kê các ước sử dụng tính chất các ước nhỏ
và lớn hơn N ở trên trong bài toán tính tổng các ước trên Ta có:
Đoạn chương trình xử lý chính sau:
for i:=2 to trunc(sqrt(n))+1 do
if n mod i = 0 then inc(d);
Hàm t( )n được định nghĩa là số lượng các ước của n Hai tính chất quan trọng dưới
đây của t( )n cho phép chúng ta nhanh chóng tính được nó:
Trang 101 2 ( )n (a 1)(a 1) (a k 1)
//T: biến lưu tổng số lượng các ước
Bài toán liên quan đến số nguyên tố
Đây là mảng kiến thức được sử dụng rất nhiều trong các bài toán số học Sau đâytôi xin đưa ra các dạng bài và các cách làm thường được áp dụng nhiều để giải quyết cácbài toán trên
Trang 11a Bài toán kiểm tra một số nguyên dương N có phải là số nguyên tố hay không?
Như chúng ta đã biết: số nguyên tố là số lớn hơn 1 và chỉ có 2 ước phân biệt là 1
và chính nó Dựa trên điều đó ta có các cách tiếp cận giải bài toán như sau:
Cách 1: Kiểm tra hết các số trong phạm vi từ 2 n-1 hoặc( [N/2] Nếu không tồntại ước nào thuộc đoạn trên thì N là nguyên tố và ngược lại
Đoạn chương trình xử lí chính rất đơn giản:
flag:=true;
if n <=1 then flag:=false
else
for i:=2 to n div 2 do if n mod i=0 then flag:=false;
if flag then write(N, 'la nguyen to')
else write(N, 'Khong nguyen to');
Thuật toán trên với n nhỏ (n ≤ 106) thì không có vấn đề gì vì độ phức tạp thuật toán
là O(N) Nhưng khi N≥ 106 thì nó tỏ ra không hiệu quả Khi đó ta dùng thuật toán sau:
Cách 2: Thử tất cả các số nguyên nằm trong khoảng từ 2 đến [ ( ) ]n Nếu không có
số nào là ước của n thì n là số nguyên tố:
function isPrime(x: longint): boolean;
var i: longint;
begin
if x=1 then exit(false);
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then exit(false);
exit(true);
end;
Về độ phức tạp thuật toán, để kiểm tra n có phải là một số nguyên tố hay không cần
phải mất thời gian là O ( ( ) )n Do vậy, nếu chương trình cần phải nhiều lần thực hiện việckiểm tra một số có phải là số nguyên tố hay không, thuật toán này là không hiệu quả Tuynhiên, nó là một cách tiếp cận đơn giản để giải quyết vấn đề và đặc biệt việc phát triểnthuật toán này sẽ cho ra các thuật toán khác mà tính hiệu quả được cải thiện rất nhiều
Cách 3: Sàng số nguyên tố
Trang 12Trong trường hợp bài toán cần phải nhiều lầm kiểm tra một số có phải là số nguyên
tố hay không và giá trị các số cần kiểm tra đủ nhỏ (nằm trong khoảng [1 106] thì cáchđơn giản nhất là lập sàng số nguyên tố (sàng Eratosthens):
var p: array[0 1000000] of longint;
với p[i]=1 khi i là hợp số và p[i]=0 trong trường hợp i là số nguyên tố
Trang 13fillchar(p,sizeof(p),0);
p[1]:=1;
for i:= 2 to trunc(sqrt(GMAX)) do
if p[i]=0 then for j:= i to n div i do p[i*j]:=1;
end;
//p[i]=0 thì i là nguyên tố.
b Phân tích một số thành thừa số nguyên tố
Ví dụ: N=12 được phân tích thành 22 * 3
Cách 1: Để thực hiện phân tích chúng ta chuẩn bị mảng
var Prime: array[0 1000000] of longint;
nP: longint;
Trong đó Prime[i] là số nguyên tố thứ i, còn nP là số lượng số nguyên tố kiểm soátđược Mảng Prime có thể nhanh chóng tạo ra như là một sản phẩm phụ của sàngEratosthens:
var x, y: array[0 10] of longint; sol: longint;
Với x[i] là thừa số nguyên tố thứ i, còn y[i] là lũy thừa của nó trong phân tích:
Trang 15Định lý Lagrange: Cho số nguyên dương n và số nguyên tố p Khi đó lũy thừa của
p trong phân tích n!=1.2 n thành thừa số nguyên tố là:
= 0)
Bài toán tìm UCLN và BCNN của 2 số
a Tìm UCLN của 2 số nguyên dương M, N
Cách 1: Có thể phân tích M, N thành tích của các thừa số nguyên tố rồi sau đó lấy
tích của các thừa số nguyên tố chung Đây là giải thuật phức tạp và ít được áp dụng
Cách 2: Vận dụng kiến thức toán học
Trang 16- Nếu N>M thì UCLN(N,M)= UCLN(N-M, M);
- Nếu N< M thì UCLN(N,M)= UCLN(N,M - N);
- Nếu N=M thì thì UCLN(N,M)= M hoặc N
Cách 3: Sử dụng thuật toán Euclid UCLN(m,n) = UCLN(n, (m mod n)) Đây là
giải thuật được đánh giá cao và cài đặt khá đơn giản Vì vậy nó thường được sử dụng
b Bài toán BCNN của 2 số nguyên dương M, N
Một cách đơn giản khi chúng ta biết tính UCLN:
.( , )
( , )
a b BCNN m n
UCLN a b
2.3.2 Các thuật toán về vòng lặp
a Thuật toán tính giai thừa một số
Giai thừa n! là tích các số từ 1 đến n Vậy hàm giai thừa viết như sau:
function giaithua(n : integer) : longint;
var i : integer; s : longint;
Trong Pascal ta có thể tính ab bằng công thức exp(b*ln(a)) Tuy nhiên nếu a không phải là
số dương thì không thể áp dụng được
Trang 17Ta có thể tính hàm mũ an bằng công thức lặp như sau:
function hammu(a : real; n : integer): real;
var s : real; i : integer;
x n n! , ta được công thức truy hồi:
{ s 0 =1, r 0 =1 ¿ { r i = r i-1 x
Khi đó, ta có thể tính công thức chuỗi trên như sau:
function expn(x: real; n : integer): real;
var s,r : real; i : integer;
2.3.3 Các bài toán tham khảo
Câu 1 - Số Kaprekar (Trích đề thi tin học trẻ huyện Nho Quan – tỉnh Ninh Bình
năm 2015)
Số Kaprekar được khám phá bởi nhà toán học D.R.Kaprekar người Ấn độ vào năm
1949 Số Kaprekar thỏa mãn các tính chất sau: Một số tự nhiên K có n chữ số, ta bìnhphương số K, rồi lấy n số bên phải của số vừa được bình phương cộng với số còn lại bêntrái của nó Nếu kết quả cộng lại bằng chính số K thì số K được gọi là số Kaprekar
Ví dụ 1: Số 703 có 3 chữ số, ta có 7032 = 494209, lấy 3 chữ số bên phải là 209, sốcòn lại bên trái là 494, và 209 + 494 = 703 nên số 703 là số Kaprekar
Trang 18Ví dụ 2: Số 2015 có 4 chữ số, ta có 20152 = 4060225, lấy 4 chữ số bên phải là
0225, số còn lại bên trái là 406, và 225 + 406 = 631 2015 nên số 2015 không là sốKaprekar
Yêu cầu: Cho trước số tự nhiên K, hãy xét xem K có là số Kaprekar hay không?
Dữ liệu vào từ tệp KAPREKA.INP có duy nhất số tự nhiên K (0< K≤ 25000) Kết quả được ghi vào tệp KAPREKA.OUT duy nhất số 1 nếu K là số Kaprekar,
ngược lại ghi số 0
Ví dụ:
KAPREKA.IN
P
KAPREKA.OUT
KAPREKA.INP
KAPREKA.OUT
xuli;
end
Câu 2 - Số phản nguyên tố (Trích đề thi tin học trẻ huyện Nho Quan – tỉnh Ninh Bình
năm 2015)
Trang 19Định nghĩa: Số phản nguyên tố là số có nhiều ước số nhất trong N số tự nhiên đầutiên.
Yêu cầu: Hãy tìm số phản nguyên tố trong N số tự nhiên đầu tiên.
Dữ liệu vào cho trong tệp PHANNT.INP có m+1 dòng, trong đó:
- Dòng đầu là số tự nhiên N (N≤100) là số các số cần tìm số phản nguyên tố
- m dòng tiếp theo lần lượt là các số N1, N2, N3,… Nm (1≤Ni≤ 2x109) là các số cần tìm
số phản nguyên tố
Kết quả được ghi vào tệp PHANNT.OUT gồm m dòng: dòng thứ i là số phản
nguyên tố trong Ni số tự nhiên đầu tiên
Ví dụ:
PHANNT.IN
P
PHANNT.OUT
PHANNT.INP
PHANNT.OUT
1
1000
1210002015
128401680
Code Pascal tương ứng
for j:=1 to a[i] do begin
uoc;
if d>max then begin max:=d;