Các giáo viên đều hướng dẫn cho học sinh biết một bài toán có thể được giải với nhiều thuật toán khác nhau và mỗi thuật toán chỉ giải được một bài toán hoặc một lớp bài toán, nhưng thực
Trang 1A ĐẶT VẤN ĐỀ
I Lời nói đầu
Để rèn luyện kỹ năng lập trình cho học sinh khá, giỏi trước khi chọn đội tuyển đi thi học sinh giỏi môn Tin học có rất nhiều cách mà giáo viên có thể áp dụng đối với các đối tượng học sinh khác nhau Các trường có điểm thi đầu vào cao thì việc rèn luyện kỹ năng sẽ có nhiều thuận lợi nhưng với các trường có điểm thi đầu vào trung bình và thấp thì việc rèn luyện kỹ năng lập trình cho các
em gặp rất nhiều khó khăn Tuy nhiên trong cùng một trường với các đối tượng học sinh khác nhau giáo viên có thể áp dụng nhiều biện pháp khác nhau để rèn luyện kỹ năng lập trình cho học sinh với hiệu quả khác nhau Các giáo viên đều hướng dẫn cho học sinh biết một bài toán có thể được giải với nhiều thuật toán khác nhau và mỗi thuật toán chỉ giải được một bài toán hoặc một lớp bài toán, nhưng thực tế cho thấy, đứng trước một bài toán tin học học sinh thường lúng túng khi xác định thuật toán hoặc không xác định được thuật toán, việc này cũng
có thể do nhiều nguyên nhân, chẳng hạn môn Tin học không liên quan đến thi đại học nên các em không chú tâm học, không đầu tư, do các em không có máy
để thực hành thêm ở nhà… Tuy nhiên khi cho một bài toán tin học có dạng tương tự hoặc dạng mở rộng từ một bài toán cơ bản nào đó trong sách giáo khoa, hoặc một bài toán cơ bản nào đó mà các em biết thì các em có thể xây dựng và
có hứng thú để xây dựng thuật toán cho bài toán đặt ra Vì vậy giáo viên có thể chọn các bài tập cơ bản từ đó mở rộng và phát triển để rèn luyện kỹ năng lập trình cho học sinh
Dĩ nhiên cách làm này không mới với giáo viên nhưng cách chọn các bài toán cơ bản như thế nào để học sinh có thể vận dụng và gây được hưng thú cho học sinh đó lại là điều đáng quan tâm
Với ý định “Rèn luyện kỹ năng lập trình Môn Tin học 11 cho học sinh khá, giỏi bằng việc mở rộng các bài toán cơ bản” nên trong sáng kiến kinh nghiệm này tôi muốn trình bày một kinh nhgiệm trong việc rèn luyện kỹ năng lập trình cho học sinh khi học môn Tin học 11
II Thực trạng của vấn đề
Đứng trước một bài toán tin học học sinh thường lúng túng và không biết tìm thuật toán của bài toán từ đâu và tìm như thế nào? Một số học sinh khá, giỏi thì
có thói quen là mò mẫm và thử nghiệm để tìm lời giải, điều đó có thể dẫn tới kết quả đúng hoặc sai hoặc chệch hướng giải quyết bài toán, hiệu suất để tìm thuật toán như thế là không cao, một số học sinh kém hơn thì không biết cách tìm thuật toán từ đâu và điều đó gây tâm lý chán nản cho các em Với tình hính ấy để giúp học sinh định hướng tốt hơn trong quá trình tìm thuật toán, trước khi có thể
tự tìm được thuật toán tốt hơn thì người giáo viên cần tạo cho học sinh thói quen tìm thuật toán cho bài toán đặt ra từ các các bài toán cơ bản quen thuộc mà các
em đã biết, khai thác các yếu tố đặc trưng của một số bài toán cơ bản để tìm
Trang 2thuật toán cho các bài toán mới Việc áp dụng thuật toán của các bài toán cơ bản
để xây dựng thuật toán cho các bài toán tương tự hoặc các bài toán mở rộng từ các bài toán cơ bản đó là một quá trình giúp học sinh rèn luyện kỹ năng lập trình
B GIẢI QUYẾT VẤN ĐỀ
I Các giải pháp thực hiện
1 Xây dựng hệ thống bài tập để rèn luyện kỹ năng lập trình thông qua các
buổi học, mỗi buổi học nên chọn một bài toán cơ bản để mở rộng và phát triển
kỹ năng lập trình
Mỗi buổi học nên xây dựng hệ thống bài tập như sau:
Bước 1: Chọn bài toán cơ bản hoặc bài toán quen thuộc với học sinh để
học sinh lập trình
Bước 2: Mở rộng bài toán ở cấp độ 1 (chỉ cần học sinh lập trình được mà
chưa cần quan tâm đến các yếu tố như: quan tâm đến các yếu tố đặc biệt của dữ liệu vào, thời gian, phạm vi giá trị của biến…)
Bước 3: Mở rộng bài toán ở cấp độ 2 (quan tâm đến các yếu tố như: các
trường hợp đặc biệt của dữ liệu vào, phạm vi giá trị của các biến, thời gian, chuyển sang đọc ghi vào kiểu tệp …)
Bước 4: Mở rộng bài toán để học sinh rèn luyện kỹ năng lập trình ở nhà
trên máy hoặc trên giấy sau đó nộp lại để giáo viên kiểm tra đánh giá
2 Tổ chức cho học sinh hình thành kỹ năng lập trình thông qua nhiều buổi
học có sự hướng dẫn của giáo viên tại phòng máy
3 Tổ chức kiểm tra để thu thập thông tin về khả năng rèn luyện kỹ năng
lập trình của học sinh
II Các biện pháp để tổ chức thực hiện
Nội dung này được triển khai thông qua các buổi học (mỗi buổi học 3 tiết) Số lượng buổi học là bao nhiêu buổi là do giáo viên xây dựng tùy vào chất lượng học sinh
Trong phạm vi chương trình môn tin học lớp 11, chúng ta có thể sử dụng một số hệ thống bài tập sau để rèn luyện kỹ năng lập trình cho học sinh khá, giỏi thông qua các buổi học:
BUỔI 1: (Áp dụng khi học xong các bài về các câu lệnh IF, FOR, WHILE) Bài tập 1: (bài toán cở bản): Viết chương trình nhập vào số nguyên dương N từ
bàn phím Sử dụng câu lệnh lặp FOR tính tổng sau: S= N1
3
1 2
1
quả ra màn hình
Nhận xét: Đây là bài toán có trong sách giáo khoa và học sinh cũng đã được làm quen thông qua các ví dụ nên dễ dàng lập trình được:
Program bai1;
Var i,N:word;
S:real;
Trang 3Write(‘Nhap N=’);
Readln(N);
S:=0;
For i:=1 to N do S:=S + 1/i;
Writeln(‘Tong = ‘, S:10:2);
Readln;
End
Giáo viên có thể đưa ra các bộ test tương ứng với giá trị của N để làm rõ yêu cầu
đề bài hoặc để chú ý một số trường hợp cho học sinh
Từ bài toán này ta yêu cầu học sinh làm bài tập 2 như sau:
Bài tập 2: Sửa lại chương trình ở bài tập 1 nhưng sử dụng câu lệnh lặp WHILE
3
1 2
1
1 và đưa kết quả ra màn hình
Nhận xét:
+ Từ màn hình soạn thảo của Pascal yêu cầu học sinh vào File chọn Save As để lưu lại tên tệp với tên bài 2 sau đó sửa lại chương trình bài 1 để được bài 2, bỏ bớt các biến không dùng đến (cách làm này rất tiết kiệm thời gian vì chương trình bài 2 mở rộng từ bài 1)
+ Ở bài này với học sinh khá, giỏi ở một số trường có chất lượng điểm đầu vào cao có thể giải quyết đơn giản, còn học sinh ở một số trường có điểm đầu vào thấp thì học sinh có thể băn khoăn ở việc tìm điều kiện của vòng lặp WHILE, đến đây giáo viên có thể hướng dẫn cách chuyển đổi từ vòng lặp For–To-Do (Bài tập 1) sang vòng lặp WHILE , chẳng hạn:
For i:= <GTđầu> To <Gtcuối> Do
<câu lệnh>;
i:= <GTđầu>;
While i <= <Gtcuối> Do
Begin
<câu lệnh>;
i:=i+1;
End;
Học sinh sẽ tự mình hoàn thành được chương trình
Bài tập 3:
Viết chương trình nhập vào số nguyên dương N từ bàn phím Sử dụng câu lệnh
) 1 (
4
1 3
1 2
1
Nhận xét: Học sinh sẽ thấy bài này chỉ khác với bài tập 1 là có dấu khác nhau tại các số hạng, còn chương trình thì cũng tương tự như thế nên học sinh sẽ cố gắng tìm cách đặt dấu tại các số hạng hoặc tìm cách biểu diễn (-1)N+1 trong pascal, hoặc có học sinh sẽ dùng tính chẵn lẽ của số hạng
Trang 4Tuy nhiên ta sẽ hướng dẫn học sinh dùng biến để điền dấu cho các số hạng như sau:
Program bai3;
Var i,dau,N:integer;
S:real;
Begin
Write(‘Nhap N=’);
Readln(N);
Dau:=1;
S:=0;
For i:=1 to N do
begin S:=S + dau*(1/i);
Dau := -1*dau;
End;
Writeln(‘Tong = ‘, S:10:2);
Readln;
End
Giáo viên nên giải thích tại sao lại nên dùng biến dau như vây?
Từ bài tập 3 ta sẽ chuyển sang bài tập 4 như sau:
Bài tập 4: Sửa lại chương trình ở bài tập 1 nhưng sử dụng câu lệnh lặp WHILE
) 1 (
4
1 3
1 2
1
Lúc này học sinh sẽ giải quyết một cách đơn giản
Bài tập 5: Viết chương trình nhập vào số nguyên dương N từ bàn phím Sử dụng
! 4
1
! 3
1
! 2
1
N
N
ra màn hình
Nhận xét: Học sinh dễ nhận thấy về cơ bản thì cách làm bài này cũng giống như bài 1 nhưng chỉ băn khoăn làm thế nào để tính các giai thừa? Nếu học sinh chưa biết cách tính giai thừa bằng các câu lệnh của Pascal thì giáo viên nên hướng dẫn học sinh cách tính giai thừa của một số i để xem học sinh kết hợp vào để giải bài toán này như thế nào?
Cách tính giai thừa của một số i sử dụng các câu lệnh của Pascal:
Gt:=1;
For j:=1 to i do gt:=gt*j; khi đó biến gt sẽ mang giá trị của i!
Khi đó học sinh có thể kết hợp như sau:
Program bai5;
Var j,i,dau,N:Integer;
Gt:longint; {giáo viên nên giải thích}
Trang 5Begin
Write(‘Nhap N=’);
Readln(N);
Dau:=1;
S:=0;
For i:=1 to N do
begin Gt:=1;
For j:=1 to i do gt:=gt*j;
S:=S + dau*(1/gt);
Dau := -1*dau;
End;
Writeln(‘Tong = ‘, S:10:2);
Readln;
End
Giáo viên yêu cầu học sinh tối ưu lại chương trình bằng cách sử dụng một vòng lặp để xem học sinh làm thế nào? Nếu học sinh vẫn còn lúng túng thì giáo viên nên lấy ví dụ minh họa với N = 5 chẳng hạn, mô phỏng trạng thái của các biến trong chương trình để học sinh hiểu được thuật toán với một vòng lặp Giáo viên yêu cầu học sinh phải hoàn thiện chương trình với một vòng lặp như sau:
Program bai5;
Var j,i,dau,N:integer;
Gt:longint; {giáo viên nên giải thích}
S:real;
Begin
Write(‘Nhap N=’);
Readln(N);
Dau:=1;
S:=0; gt:=1; {Khởi tạo biến gt ở dây}
For i:=1 to N do
begin gt:=gt*i;
S:=S + dau*(1/gt);
Dau := -1*dau;
End;
Writeln(‘Tong = ‘, S:10:2);
Readln;
End
Trang 6Tuy vậy sẽ có học sinh sẽ khởi tạo S:=1; giáo viên nên phân tích và hướng dẫn trường hợp này
Bài tập 6: Sửa lại chương trình ở bài tập 5 nhưng sử dụng câu lệnh lặp WHILE
! 4
1
! 3
1
! 2
1
N
N
Bằng cách lưu và sửa lại chương trình ở bài tập 5 học sinh sẽ giải quyết một cách nhanh chóng
(Giáo viên yêu cầu học sinh về nhà đọc thêm câu lện Repeat …Until nếu chưa dạy thêm) để làm các bài tập sau đây để nộp lại cho giáo viên vào ngày nào đó trong tuần để giáo viên kiểm tra
Bài tập 7: Sử dụng câu lệnh lặp Repeat … Until viết lại các bài toán từ 1 đến 6
với điều kiện 1<N<100 Sử dụng câu lệnh Repeat … Until để kiểm tra điều kiện nhập giá trị của N
Giáo viên yêu cầu học sinh trình bày ra giấy và sau đó thu lại (Thực chất nếu giáo viên đã hướng dẫn học sinh về câu lệnh Repeat … Until thì học sinh có thể làm ngay tại phòng máy được)
Vậy sau khi học xong buổi 1 ta đã rèn luyện được một số kỹ năng vận dụng các câu lệnh IF, FOR, WHILE và chuyển đổi qua lại giữa các câu lệnh, học sinh sẽ có cảm giác thích thú hơn
BUỔI 2: Một số bài toán về ước số Bài tập 1: (bài toán cơ bản)
Viết chương trình nhập từ bàn phím số nguyên dương N, tính tổng các ước thực
sự của N và in ra màn hình Ví dụ: N=6 thì tổng các ước là 1+2+3 =6; N=9 thì tổng các ước là 1+ 3 =4
Nhận xét: Học sinh biết để kiểm tra xem số i có phải là ước của số N hay không thì dùng phép toán Mod (N mod i = 0), giáo viên chỉ cần hướng dẫn học sinh duyệt các số i đó trong khoảng từ 1 đến (N div 2) là học sinh có thể làm được nhanh chóng, ta sẽ có đáp án của bài này có thể như sau:
Program bai1;
Var i,tg,N:word;
Begin
Write(‘Nhap N=’);
Readln(N);
Tg:=0;
For i:=1 to N div 2 do
If n mod i =0 then tg:=tg+i;
Writeln(‘Tong cac uoc la= ‘, tg:5);
Readln;
End
Trang 7Giáo viên có thể yêu cầu học sinh nhập một vài giá trị N để xem kết quả Sau đó yêu cầu học sinh làm bài tập 2 như sau:
Bài tập 2: Số N được gọi là số hoàn hảo nếu tổng các ước thực sự của N bằng
chính nó Viết chương trình nhập từ bàn phím số nguyên dương N, thông báo ra màn hình DUNG nếu N là số hoàn hảo, ngược lại thì thông báo KHONG
Nhận xét: Học sinh dễ dàng nhận thấy cách làm bài 2 sẽ tương tự cách làm bài 1, chỉ thêm một công việc đó là kiểm tra xem tổng các ước đó có bằng N hay không? Học sinh sẽ nhanh chóng sao chép chương trình bài1 và sửa lại để được chương trình bài 2 như sau:
Program bai2;
Var i,tg,N:word;
Begin
Write(‘Nhap N=’);
Readln(N);
Tg:=0;
For i:=1 to N div 2 do
If n mod i =0 then tg:=tg+i;
If tg=N then Writeln(‘DUNG’) else writeln(‘KHONG’);
Readln;
End
Tương tự như vậy ta sẽ yêu cầu học sinh làm bài tập 3 như sau:
Bài tập 3: Viết chương trình in ra màn hình các số hoàn hảo trong khoảng từ a
đến b (với 1<a<b) Với a, b được nhập từ bàn phím
Nhận xét: Giáo viên để cho học sinh tự làm, nếu còn học sinh nào còn lúng túng thì mới hướng dẫn Tuy nhiên thì với bài 2 đã biết cách làm thì học sinh cũng có thể nhanh chóng hoàn thiện được bài 3 có thể chưa kiểm tra được điều kiện nhập a,b như sau:
Program bai3;
Var i,a,b,k,tg:word;
Begin
Write(‘Nhap a,b=’);
Readln(a,b);
For k:=a to b do
Begin Tg:=0;
For i:=1 to K div 2 do
If K mod i =0 then tg:=tg+i;
If tg=K then Writeln(k);
End;
Readln;
Trang 8Giáo viên yêu cầu học sinh test với một số bộ dữ liệu tương ứng với các giá trị của a, b và yêu cầu học sinh hoàn thiện thêm đọan lệnh kiểm tra điều kiện nhập a,b bằng repeat until
Bài tập 4: Lập chương trình tìm tất cả các số hoàn hảo nhỏ hơn số nguyên N (N
>=10), in các số hoàn hảo và và các ước của số tìm được ra màn hình Giá trị của N được nhập từ bàn phím
Tương tự ta yêu cầu học sinh sao chép sửa lại chương trình bài tập 3 để được bài tập 4
Bài tập 5: Hai số a và b được gọi là bạn của nhau nếu tổng các ước của a bằng b
và ngược lại tổng các ước của b bằng a Viết chương trình tìm các số bè bạn như trên trong khoảng từ m đến n (m < n, m và n nhập từ bàn phím)
Tương tự ta yêu cầu học sinh sao chép sửa lại chương trình bài tập 4 để được bài tập 5
Bài tập 6: (Bài tập về nhà)
Viết chương trình nhập vào 2 số a, b (1<a<b<10000) Thông báo ra màn hình số lượng các số chẵn, số lượng các số lẽ, số lượng các số hoàn hảo trong khoảng từ a đến b, với a, b được nhập từ bàn phím
Bài tập 7: (Bài tập về nhà)
Em hãy dùng câu lệnh while để viết lại chương trình của bài 4 và bài 5 Yêu cầu: Kiểm tra điều kiện nhập dữ liệu vào Viết chương trình ra giấy và nộp lại cho giáo viên
Sau buổi 2 kỹ năng vận dụng các cấu trúc vòng lặp For- If, While - if lồng nhau đã đựoc cải thiện hơn
BUỔI 3: Một số bài toán về số nguyên tố Bài tập 1: (Bài toán cơ bản)
Viết chương trình nhập vào từ bàn phím số nguyên N, Kiểm tra và thông báo ra màn hình N là số nguyên tố hoặc N không là số nguyên tố
Nhận xét: Bài toán này học sinh đã được tìm hiểu thuật toán từ lớp 10, nếu học sinh quên giáo viên có thể nêu lại thuật toán để học sinh nhớ lại Ở đây ta chưa cần hướng dẫn cho học sinh thuật toán tốt để kiểm tra số nguyên tố Chương trình có thể như sau:
Program b1;
Var i,n:integer;
kq:boolean;
begin
write('N = ');readln(n);
kq:=true;{Giả sử N là SNT, Gán kq bằng true}
if n<=1 then kq:=false
else
Trang 9for i:=2 to trunc(sqrt(n)) do{i chạy từ 2 đến phần nguyên căn bậc 2 của N}
if n mod i=0 then{Nếu n chia hết cho i thì}
begin
kq:=false;{Gán kq=false}
break;{thoát vòng lặp bằng lệnh Break}
end;
if kq then writeln('So nguyen to') else write('Khong la so nguyen to'); readln;
end
Bài tập 2: 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
Nhận xét: Học sinh sẽ áp dụng thuật toán của bài 1 để giải quyết bài 2 Giáo viên nên để học sinh tự làm, nếu còn lúng túng thì mới hướng dẫn thuật toán Sau khi
áp dụng bài 1, sao chép và sửa lại chương trình bài 1 để có chương trình bài 2, chương trình có thể được học sinh viết như sau:
Program b2;
Var i,k,n:integer;
kq:boolean;
begin
write('N = ');readln(n);
For k:=1 to N do
begin
kq:=true;{Giả sử k là SNT, Gán kq bằng true}
if K<=1 then kq:=false
else
for i:=2 to trunc(sqrt(K)) do{i chạy từ 2 đến phần nguyên căn bậc 2 của k}
if k mod i=0 then{Nếu n chia hết cho i thì}
begin
kq:=false;{Gán kq=false}
break;{thoát vòng lặp trong bằng lệnh Break}
end;
if kq then write(k:5);
end;
readln;
end
Sau khi học sinh hoàn thành chương trình giáo viên nên đưa ra một số bộ test tương ứng với các giá trị của N để học sinh chạy thử và hoàn thiện điều khiện nhập dữ liệu cho chương trình
Bài tập 3: Cho số nguyên N chẵn (nhập từ bàn phím), lập chương trình phân tích
N thành tổng 2 số nguyên tố Nếu có in ra các cách phân tích VD: 6 = 3+ 3
Trang 10Nhận xét: Học sinh sẽ vận dụng thuật toán của bài 1 và 2 để giải quyết bài 3 Giáo viên nên để học sinh tự làm, nếu còn lúng túng thì mới hướng dẫn thuật toán Chương trình có thể được học sinh viết như sau:
program bai3;
var N,i , j, k, m,d : longint;
kq1, kq2:boolean;
begin
writeln(‘Nhap N= ‘); readln(N);
begin {kiem tra xem so i co phai la so nguyen to hay khong}
kq1:=true;
for k:=2 to trunc(sqrt( i )) do {vong lap 2}
if i mod k =0 then
begin kq1:=false;{do i chia het cho k nen i khong nguyen to}
break;
end;
if kq1 then {neu so i la snto thi tim so j la so nto ma i+j=N}
begin {kiem tra xem so j co phai la so nguyen to hay khong}
kq2:=true;
for m:=2 to trunc(sqrt( j )) do
if j mod m=0 then begin
kq2:=false;{Gan kq2=false, tuc j khong la so nto}
break;
end;
if kq2 then
if i+j = N then begin
writeln(N ,' = ', i, ' + ', j);
d:=d+1;
end;
end;
end;
readln;
End
Giáo viên giải thích cho học sinh tại sao ở {vong lap 1} biến i lại nhận giá trị bắt dầu từ 2? Tại sao không cần câu lệnh kiểm tra i<=1 trước {vong lap 2}