Tin học là một môn học mới, việc truyền đạt kiến thức cơ bản trong sách giáo khoa đã là khó khăn, làm sao để dạy học bồi dưỡng học sinh khá giỏi.. Giúp các em không chỉ nắm được những ki
Trang 1A ĐẶT VẤN ĐỀ I/ LÝ DO CHỌN ĐỀ TÀI
Ngày nay cùng với sự phát triển của đất nước, công nghệ thông tin đang đóng một vai trò hết sức quan trọng, tác động đến hầu hết các lĩnh vực của đời sống xã hội Việc đào tạo một thế hệ tương lai có một sự phát triển toàn diện đòi hỏi ngành giáo dục luôn phải có sự quan tâm đúng mức là điều rất cần thiết để
có một nguồn nhân lực đáp ứng yêu cầu CNH, HĐH mở cửa và hội nhập hướng tới nền kinh tế tri thức của nước ta nói riêng và thế giới nói chung
Tin học là một môn học mới, việc truyền đạt kiến thức cơ bản trong sách giáo khoa đã là khó khăn, làm sao để dạy học bồi dưỡng học sinh khá giỏi Giúp các em không chỉ nắm được những kiến thức cơ bản mà còn hiểu và giải quyết được những bài toán đòi hỏi những thuật toán phức tạp hơn: Hoán vị, tổ hợp, đó
là việc khiến các giáo viên phải luôn luôn trăn trở và tìm những phương pháp phù hợp
Một thuật toán chỉ giải được một bài toán, nhưng một bài toán lại có thể
có rất nhiều thuật toán khác nhau Làm thế nào để tìm ra thuật toán phù hợp, nhanh gọn, dễ hiểu, tốn ít dung lượng bộ nhớ Phương pháp đệ qui là một phương pháp hay, có nhiều ưu điểm nhưng cũng có nhược điểm là rất tốn bộ nhớ Ngoài ra kiến thức mới cũng làm học sinh khó hấp thụ Cách giải những bài toán phức tạp nhưng dùng những kiến thức cũ đôi khi giúp học sinh dễ hiểu hơn Từ những lí do trên tôi đã quyết định chọn đề tài “Mảng 1 chiều trong kĩ
thuật khử đệ qui để bồi dưỡng học sinh giỏi Tin học 11”.
Trang 2B GIẢI QUYẾT VẤN ĐỀ.
I/ CƠ SỞ LÝ LUẬN:
+ Luật giáo dục nước ta đã cụ thể hoá tại chương II, mục 2 điều 23 là:
“Mục tiêu của giáo dục phổ thông là giúp học sinh phát triển toàn diện về đạo đức, trí tuệ, thể chất, thẩm mỹ và các kỹ năng cơ bản nhằm hình thành nhân cách con người Việt Nam xã hội chủ nghĩa, xây dựng tư cách và trách nhiệm công dân, chuẩn bị cho học sinh tiếp tục học lên hoặc đi vào cuộc sống lao động tham gia xây dựng và bảo vệ Tổ Quốc”
+ Môn tin học, cũng như mọi môn học khác, căn cứ vào mục tiêu trên để xác định nhiệm vụ cụ thể của môn học, tổ chức hoạt động đào tạo góp phần thực hiện mục tiêu giáo dục mà Đảng và nhà nước đề ra
+ Ngoài việc tạo điều kiện cho học sinh chiếm lĩnh những tri thức và kỉ năng Tin học cần thiết, Tin học còn có tác dụng phát triển năng lực trí tuệ chung như: phân tích, tổng hợp, trừu tượng hoá, khái quát hoá…rèn luyện những đức tính, phẩm chất của người lao động mới Học sinh sẽ thấy rõ hiệu quả mạnh mẽ của công nghệ thông tin và nhận thức cần có
II/ THỰC TRẠNG VẤN ĐỀ
Thực trạng chung:
Hiện nay nhu cầu xã hội đang rất cần những kĩ sư Công Nghệ Thông tin
có trình độ cao Tuy nhiên việc đào tạo và bồi dưỡng học sinh yêu thích môn Tin học ở trường Phổ thông hiện nay đang gặp rất nhiều khó khăn
Tin học 11 là một môn học mới, để học tốt được lập trình đòi hỏi học sinh phải có một kiến thức cơ bản tốt, phải có khả năng tư duy và niềm đam mê, ngoài ra học sinh phải có điều kiện thực hành thường xuyên
Đa số các em học sinh tập trung học các môn khối để ôn thi đại học nên không dành được nhiều thời gian cho môn Tin học Trường đã có máy tính để thực hành nhưng số lượng ít chưa đủ để tất cả các tiết thực hành đều được đáp ứng Tài liệu tham khảo dành cho môn tin học chưa có nhiều nên việc tiếp cận với những kiến thức mới còn gặp nhiều khó khăn Đó là cũng thực trạng chung của hầu hết các trường phổ thông hiện nay
* Một số thuận lợi và khó khăn khi thực hiện đề tài ở trường THPT Tĩnh Gia I
1 Thuận lợi:
* Nhà trường:
- Trường THPT Tĩnh Gia 1 là ngôi trường có truyền thống với bề dày 53 năm Là trường chuẩn quốc gia nên trường cũng là nơi có điều kiện cơ sở vật
Trang 3chất tương đối đảm bảo đáp ứng cho điều kiện học tập Nhà trường đã tạo điều kiện để học sinh có điều kiện tốt nhất để học, tạo điều kiện về máy móc, trang thiết bị phục vụ cho việc dạy và học môn Tin học
* Học sinh:
Là môn học có tính ứng dụng cao nên đa số học sinh có ý thức tìm hiểu về môn học nói riêng và CNTT nói chung Một số học sinh có khả năng phát triển
về lập trình và yêu thích lập trình Có nhiều gia đình đã có máy vi tính nên các
em cũng có điều kiện thực hành
2 Khó khăn:
* Nhà trường:
Nhà trường đã có hai phòng máy vi tính để cho học sinh học nhưng vẫn còn hạn chế về số lượng cũng như chất lượng, mỗi ca thực hành có tới 2 – 3 em ngồi cùng một máy nên các em không có nhiều thời gian để thực hành làm bài tập một cách đầy đủ Tuy đã có hai phòng thực hành nhưng số lớp nhiều (35 lớp học) và mỗi lớp số lượng học sinh khoảng 40 - 45 học sinh, tất cả các lớp đều học buổi sáng, tiết học thực hành cũng nằm trong phân phối chương trình với các tiết khác nên không thể tránh khỏi việc chồng chéo trong việc đăng kí lịch thực hành giữa các lớp
* Giáo viên:
Đa số các giáo viên đều còn trẻ nên còn chưa có nhiều kinh nghiệm Môn tin học mới đưa vào giảng dạy nên giáo viên thường gặp khó khăn về phân hoá học sinh và bồi dưỡng học sinh yêu thích và học khá giỏi môn tin Do đó việc lựa chọn học sinh giỏi là rất khó khăn vì học sinh giỏi thường học tốt các môn tự nhiên
* Học sinh:
Có nhiều học sinh có kiến thức cơ bản tốt và có tư duy nhưng các em lại không có máy tính thực hành ở nhà hoặc chỉ dành thời gian cho các môn khối
mà không chọn vào đội tuyển thi học sinh giỏi môn Tin Học sinh đa số chưa tiếp cận ngôn ngữ lập trình nên rất khó khăn trong học lập trình Các bài toán yêu cầu giải thuật đệ qui thường khó lại là kiến thức mới ngoài sách giáo khoa nên học sinh khó tiếp cận và thực hiện
III/ GIẢI PHÁP VÀ TỔ CHỨC THỰC HIỆN
- Học sinh được bồi dưỡng thi học sinh giỏi không chỉ cần nắm vững kiến thức trong sách giáo khoa mà còn phải có khả năng tư duy tốt để giải quyết các bài toán khó Việc dạy học không chỉ là truyền đạt kiến thức cho các em mà giáo
Trang 4viên còn phải kích thích sự sang tạo, niềm đam mê, sự say mê học hỏi và muốn tìm hiểu cái mới
*Đệ qui: là một kiến thức mới mà học sinh chưa được học trong sách giáo
khoa Một thủ tục gọi là đệ qui nếu trong quá trình thực hiện nó có phần phải gọi đến chính nó nhưng với kích thước nhỏ hơn của tham số
- Đệ qui mạnh ở chỗ có thể định nghĩa một tập rất lớn các tác động chỉ bởi một số hữu hạn các mệnh đề Một chương trình viết theo dạng đệ qui trông sẽ sáng sủa hơn, ngắn gọn hơn
- Tuy nhiên đệ qui cũng có nhược điểm là nếu bài toán dùng giải thuật đệ qui đòi hỏi dữ liệu phải tính toán nhiểu, đòi hỏi thời gian chạy chương trình lâu hơn và sẽ dẫn đến tốn bộ nhớ của máy tính
*Khử đệ qui: Có một số giải thuật đệ qui thuộc loại tính toán đơn giản có
thể thay thế bởi một giải thuật khác không tự gọi nó, sự thay thế đó được gọi là khử đệ qui Vì vậy có một số bài toán ta có thể thay bằng những thuật toán khử
đệ qui
Tôi xin giới thiệu một số bài toán có bản chất đệ qui nhưng có thể giải bằng phương pháp khử đệ qui Thay bằng việc dùng các thủ tục đệ qui chúng ta
có thể dùng mảng 1 chiểu để lưu các giá trị đã được tính toán Việc dùng mảng một chiều là 1 kiến thức cũ sẽ làm học sinh dễ hiểu hơn, nó cũng là một cách để chúng ta so sánh các cách giải 1 bài toán và nâng cao khả năng tư duy của học sinh
Ví dụ 1: Tìm số fibonaci thứ n.
Mô tả cây nhị phân tìm kiếm số Fib(4) theo kiểu đệ qui có dạng cây như sau:
F(5) =F(4)+ F(3)
F(4) =F(3)+ F(2)
F(3) =F(2)+ F(1) F(2) =1
F(3) =F(2)+ F(1)
F(2) = 1 F(1) = 1
Trang 5Để tính được F(5) ta phải gọi F(4) và F(3), tính được F(4) phải gọi F(3) và F(2), F(1) và F(2) đã cho từ ban đầu
Function Fib(n:integer):integer;
Begin
If n=1 then fib:=1 else
If n=2 then fib:=1 Else fib:=fib(n-1)+ fib(n-2);
End;
Nếu dùng thủ tục đệ qui thay bằng việc gọi các giá trị từ trên xuống ta sẽ tính các giá trị nhỏ trước và lưu các giá trị đó vào mảng 1 chiều
Và ta có sơ đồ cây tính toán như sau:
F(5) =F(4)+ F(3)
F(4) =F(3)+ F(2)
F(3) =F(2)+ F(1) F(2) =1
F(3) =F(2)+ F(1)
F(2) = 1 F(1) = 1
F(1) =1 F(2) =1
A[5] =A[4] + A[3]
A[3] =A[1]+ A[2]
A[4] =A[3] + A[2]
A[5] =A[4] + A[3]
A[3] =A[1]+ A[2]
A[4] =A[3]
+A[2]
Trang 6Nhìn vào sơ đồ 2 ta thấy các giá trị phải tính toán ít hơn sơ đồ 1.
Ta có thủ tục minh hoạ sau:
Procedure fib;
Begin
A[1]:=1;
A[2]:=1;
For i:=3 to n do a[i]:=a[i-1]+a[i-2];
Write(‘so fibonaci thu’,n,’la’,a[n]);
End;
Trong cách giải thứ nhất để tìm ra số fibonaci thứ n ta phải tính tất cả các giá trị trước đó Tuy nhiên các giá trị tính toán trước đó không được lưu lại Đối với cách giải thứ 2 tất cả các giá trị được lưu trong mảng A nên khi cần sử dụng lại những giá trị trước đó máy tính sẽ không phải tính lại Để thấy rõ hơn ưu nhược điểm của 2 cách ta xét ví dụ 1.2
Ví dụ 2: Tính tổng 2 số fibonaci thứ n và thứ (n -2)
- Nếu dùng cách giải đệ qui ta có thể tính tổng rất nhanh bằng cách gọi 1 lời gọi trong chương trình chính:
Tong:=fib(n)+ fib(n-2);
Tuy nhiên với lời gọi trên thì máy tính sẽ phải tính n + (n-2)=2n-2 phép toán
Trong khi nếu dùng mảng 1 chiều như trong cách 2 bài 1.1
Ta chỉ cần tính: Tong:=a[n]+a[n-2];
Với phương pháp này các giá trị đã được lưu vào mảng nên máy tính chỉ phải tính 1 lần và số phép tính thực hiện là: n
Ví dụ 3: Số siêu nguyên tố là số mà khi bỏ một chữ số tùy ý các chữ số bên phải
của nó thì phần còn lại vẫn tạo thành một số nguyên tố Viết chương trình in ra các số siêu nguyên tố có n chữ số (n nhập từ bàn phím)
VD: 7331 là một số siêu nguyên tố có 4 chữ số vì 733,33,7 cũng là các số nguyên tố
Đây là một bài toán có tính chất rất đệ qui Vì số siêu nguyên tố có I chữ
số sẽ được tạo thành từ các số siêu nguyên tố có i-1 chữ số Để kiểm tra số 7331
Trang 7có phải là số siêu nguyên tố hay không ta cần kiểm tra tính nguyên tố của 7331
và tính siêu nguyên tố của 733, tương tự để kiểm tra siêu nguyên tố của 733 ta lại phải kiểm tra tính nguyên tố của 733 và tính siêu nguyên tố của 73, tương tự lại kiểm tra tính nguyên tố của 73 và tính siêu nguyên tố của 7, 7 là số nguyên tố
và chỉ có một chữ số nên kết luận 7331 là số siêu nguyên tố
Có thể dùng hàm sieungto(n) được viết như sau:
Funtion sieungto(n:integer):boolean;
Begin
If (n=2) or (n=3)or (n=5) or (n=7) then
sieungto(n)=true else
Sieungto(n)=sieungto(n div 10) and ngto(n);
end;
Ở đây thay bằng việc tính từ trên xuống ta sẽ làm theo các công việc sau:
Ý tưởng giải bài toán:
B1 - a[1]=0 ;
B2 - i<-1, b[1]<=0;
B3 - Duyệt từng phần tử của mảng a,
- Duyệt cs từ 1 đến 9;
- Kiểm tra nếu a[i]*10 +cs là số nguyên tố thì thêm giá trị này vào mảng b;
B4 - Gán mảng a=b;
B5 - Nếu i>n thì ra mảng a, ngược lại quay lại bước 3
Ta có sơ đồ hình cây minh hoạ mảng a gồm các phần tử là số siêu nguyên
tố có n chữ số với n=3
N=1
223 239 293 311 313 317
N=3
N=2
Trang 8Chương trình minh hoạ bài toán dùng phương pháp khử đệ qui.
program sieu_nguyen_to;
var a,b:array[1 10000] of qword;
cs,ka,kb,i,n,k:byte;
function ngto(c:qword):boolean;
var x:qword;
begin
x:=2;
while (x<=sqrt(c)) and (c mod x<>0) do inc(x);
if x>sqrt(c) then kt:= true else kt:=false;
if (c=1) or (c=0) then kt:=false else if c=2 then
kt:=true;
end;
begin
repeat
write('nhap n');
readln(n);
k:=0;ka:=1; a[1]:=0;
while k<n do
begin
inc(k);
kb:=0;
for i:=1 to ka do for cs:=0 to 9 do
begin
if ngto(a[i]*10 +cs) then
begin
inc(kb);
b[kb]:=a[i]*10 +cs;
end;
end;
ka:=kb;
a:=b;
end;
writeln(ka);
for i:=1 to ka do writeln(a[i],' ');
until n=0;
End.
Ví dụ 4: Hoán vị:
Trang 9Viết chương trình nhập vào số tự nhiên n (0<n<9) in ra các hoán vị của n chữ số
tự nhiên liên tiếp từ 1 đến n
132 213 231 312 321 Đây cũng là 1 bài toán mang tính chất rất đệ qui Nhưng ở đây ta có thể dùng phương pháp khử đệ qui tương tự như ví dụ 3
Ý tưởng giải bài toán:
Ta cũng dùng 2 mảng a và b trong đó mảng a để lưu các giá trị tìm được ở mỗi bước;
- Duyệt từng phần tử của mảng a, trong mỗi phần tử ta thực hiện duyệt các giá trị j từ 1->n nếu số nào chưa có mặt trong a[h] thì ta chèn số đó vào a[h] và cho vào mảng b;
- Gán mảng a<- b; quá trình cứ tiếp tục cho đến khi i=n thì dừng, tất cả các hoán vị đã chứa trong mảng a
Ta có sơ đồ minh hoạ khi n = 3
Chương trình minh hoạ dùng mảng 1 chiều viết theo phương pháp khử đệ qui như sau:
PROGRAM hoan_vi;
type mang=array[1 1000]of string[9];
var a,b:mang;
tg:string;
I=1
I=n
Trang 10BEGIN
write('nhap n');readln(n); ka:=1; a[1]:='';
i:=0;
while i<n do
begin
i:=i+1;kb:=0;
for h:=1 to ka do
for j:=1 to n do
begin
tg:=chr(ord(j)+48);
if pos(tg,a[h])=0 then
begin
kb:=kb+1;
b[kb]:=a[h]+tg;
end;
end;
a:=b; ka:=kb;
end;
for i:=1 to ka do writeln(a[i]:7);
readln
END.
Khi thực hiện chương trình ta nhận thấy nếu n=7, 8 với phương pháp đệ qui máy tính sẽ chạy chậm hơn chương trình viết theo phương pháp khử đệ qui (có thể quan sát bằng mắt thường)
Bài tập 5: Viết chương trình in ra tất cả các dãy nhị phân có độ dài n (n nguyên
và nhập từ bàn phím)
Ví dụ: n=2 ta có ma trận nhị phân là các số biểu diễn nhị phân của các số thập phân từ 0->n2-1
VD:
01 10 11
Ý tưởng giải bài toán:
Trang 11Trong bài này ta cũng dùng 2 mảng 1 chiều a và b Thuật toán tương tự như bài hoán vị
- Ta dùng 2 mảng a và b: trong đó mảng a để lưu các giá trị tại các thời điểm của I;
- Mảng b được tạo từ mảng a bằng cách kiểm tra từng phần tử của a, đối với mỗi giá trị a[h] ta thực hiện duyệt j từ 0->1 và lần lượt chèn vào cuối xâu a[h], đó chính là 1 phần tử mới của b[kb];
- Gán ab;
- Các bước trên lặp lại cho đến khi nào i=n
Ta có sơ đồ kết quả khi n=3 như sau:
Sau đây là chương trình minh hoạ bài toán viết bằng phương pháp khử đệ qui
PROGRAM nhi_phan;
type mang=array[1 1000]of string[10];
var a,b:mang;
tg:string;
i,j,ka,kb,h,n:byte;
BEGIN
write('nhap n');readln(n); ka:=1; a[1]:='';
i:=0;
while i<n do
begin
i:=i+1;kb:=0;
for h:=1 to ka do
for j:=0 to 1 do
begin
N=1
000 001 010 011 100 101 110 111
N=3
N=2
Trang 12tg:=chr(ord(j)+48);
begin
kb:=kb+1;
b[kb]:=a[h]+tg;
end;
end;
a:=b; ka:=kb;
end;
for i:=1 to ka do write(a[i]:7);
readln
END.
Ví dụ 6: Chỉnh hợp lặp:
Viết chương trình nhập vào số tự nhiên n (0<n<10), In ra tất cả các chỉnh hợp lặp của n số tự nhiên liên tiếp từ 1 đến n
112 113 121 122 123 131 132 133
… 331 332 333 Đây là một bài toán có tính chất rất đệ qui và đã được trình bày trong nhiều tài liệu:
Chương trình dưới đây dùng phương pháp khử đệ qui, với việc dùng 2 mảng a và b để lưu các giá trị tìm được tương ứng với I từ 1 đến n
Ý tưởng giải bài toán:
Dùng 2 mảng 1 chiều a và b trong đó;
- Mảng a để lưu các giá trị tìm được tại mỗi thời điểm;
Trang 13- Mảng b được tạo bằng cách duyệt từng phần tử của mảng a, đối với mỗi phần tử a[h] ta cho j chạy từ 1n, đổi j từ sốxâu rồi chèn vào a[h] đó chính là một giá trị mới của mảng b;
- ab;
- Quá trình trên lặp lại cho đến khi i=n;
Ta có sơ đồ minh hoạ kết quả khi n=3
Chương trình sau đây được viết bằng phương pháp khử đệ qui
PROGRAM Chinhhoplap;
type mang=array[1 1000]of string[9];
var a,b:mang;
tg:string;
i,j,ka,kb,h,n:byte;
BEGIN
write('nhap n');readln(n); ka:=1; a[1]:='';
i:=0;
while i<n do
begin
i:=i+1;kb:=0;
for h:=1 to ka do
for j:=1 to n do
begin
tg:=chr(ord(j)+48);
begin
kb:=kb+1;
b[kb]:=a[h]+tg;
end;
end;
a:=b; ka:=kb;
I=1
i=n
121 122 123 131 132 133 113
112