1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Vận dụng một số thuật toán sắp xếp vào giải bài tập tin học trong bồi dưỡng học sinh giỏi

20 67 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 40,34 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Một trong các chuyên đề mà học sinh cần học tập và rèn luyện nhiều trong khi lập trình là các thuật toán về sắp xếp.. Bước đầu học sinh còn rất lúng túng trong việc xác định và vận dụng

Trang 1

MỤC LỤC

1 MỞ ĐẦU 2

1.1 Lí do chọn đề tài 2

1.2 Mục đích nghiên cứu 2

1.3 Đối tượng nghiên cứu 2

1.4 Phương pháp nghiên cứu 2

2 NỘI DUNG SÁNG KIẾN KINH NGHIỆM 3

2.1 Cơ sở lý luận 3

2.1.1 Thuật toán sắp xếp nổi bọt (bubble sort) 3

2.1.2 Thuật toán sắp xếp nhanh (quick sort) 4

2.1.3 Thuật toán sắp xếp phân phối 5

2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm 6

2.3 Các giải pháp sử dụng để giải quyết vấn đề 6

2.3.1 Một số bài tập áp dụng thuật toán sắp xếp nổi bọt 6

2.3.2 Một số bài tập áp dụng thuật toán sắp xếp nhanh 11

2.3.3 Một số bài tập áp dụng thuật toán sắp xếp phân phối 16

2.4 Hiệu quả của đề tài 17

3 KẾT LUẬN 19

3.1 Kết luận 19

3.2 Kiến nghị 19

Trang 2

1 MỞ ĐẦU

1.1 Lí do chọn đề tài.

Trong quá trình dạy học tại trường THPT Tĩnh Gia 1, nhiều năm học tôi được nhà trường phân công giảng dạy khối 11 và dạy bồi dưỡng học sinh giỏi Tôi nhận thấy để học sinh đạt kết quả cao trong việc học bồi dưỡng thì giáo viên đóng một vai trò quan trọng trong việc định hướng các chuyên đề và hướng dẫn học sinh thực hiện

Một trong các chuyên đề mà học sinh cần học tập và rèn luyện nhiều trong khi lập trình là các thuật toán về sắp xếp Bước đầu học sinh còn rất lúng túng trong việc xác định và vận dụng sao cho hợp lý các thuật toán sắp xếp để bài toán được giải quyết bằng một thuật toán tối ưu nhất

Nhằm nâng cao chất lượng dạy học môn Tin học 11, bồi dưỡng học sinh

khá giỏi Vì vậy tôi chọn đề tài: “Vận dụng một số thuật toán sắp xếp vào giải bài tập tin học trong bồi dưỡng học sinh giỏi”.

1.2 Mục đích nghiên cứu.

- Nghiên cứu tổng quan về mô phỏng thuật toán

- Trong phạm vi đề tài của mình tôi muốn nghiên cứu một số bài tập có áp dụng các thuật toán sắp xếp, nhằm giúp học sinh hình thành kỹ năng tư duy, phân tích bài toán và có thể áp dụng thuật toán sắp xếp giải bài toán tin học với những vấn đề thường gặp trong khi lập trình

1.3 Đối tượng nghiên cứu.

- Học sinh khá giỏi lớp 11 trường THPT Tĩnh Gia 1

- Một số bài toán áp dụng thuật toán sắp xếp

1.4 Phương pháp nghiên cứu.

- Phương pháp nghiên cứu xây dựng cơ sở lý thuyết

- Kỹ thuật phân tích thuật toán

Trang 3

- Tham khảo tài liệu là các tài liệu mở trên mạng internet và phân tích có

hệ thống các dạng bài tập theo nội dung đã đề ra

2 NỘI DUNG SÁNG KIẾN KINH NGHIỆM

2.1 Cơ sở lý luận

2.1.1 Thuật toán sắp xếp nổi bọt (bubble sort)

Ví dụ bài toán: Cho dãy A gồm có N phần tử a1,a2,…an Hãy sắp xếp dãy

A thành dãy không giảm

Ý tưởng của thuật toán: Là tìm và đổi chỗ các cặp phần tử kề nhau chưa

đúng thứ tự Có thể tiến hành từ bên trái sang hoặc từ bên phải sang cho đến khi không tồn tại cặp nào sai thứ tự ( dãy được sắp xếp)

Mô tả ý tưởng:

- Lượt 1: Ta xét từ cuối dãy, nếu gặp hai phần tử kề nhau mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt 1, phần tử nhỏ thứ nhất được đưa về vị trí 1

- Lượt 2: Ta xét từ cuối dãy ( chỉ đến phần tử thứ 2), nếu gặp 2 phần tử kề nhau mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt 2, phần tử nhỏ thứ hai được đưa về vị trí 2

- Lượt i: Ta xét từ cuối dãy ( chỉ đến phần tử thứ i), nếu gặp 2 phần tử kề nhau mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt i, phần tử có khoá nhỏ thứ i được đưa về vị trí i

- Xong lượt thứ n -1 thì dãy được sắp xếp xong

Chương trình:

Procedure boubblesort;

Var i,j,tg: integer;

Begin

For i:=1 to n-1 do

For j:=n downto i+1 do

If a[j-1]>a[j] then

Begin

Tg:=a[j];

A[j]:=a[j-1];

A[j-1]:=tg;

End;

End;

Thuật toán có độ phức tạp: thời gian thực hiện là O(N2) [1]

Trang 4

2.1.2 Thuật toán sắp xếp nhanh (quick sort)

Ví dụ bài toán: Cho dãy A gồm có N phần tử a1,a2,…an Hãy sắp xếp dãy

A thành dãy không giảm

Ý tưởng của thuật toán:

- Sắp xếp một dãy được coi như là sắp xếp 1 đoạn từ chỉ số 1 đến chỉ số N

- Để sắp xếp 1 đoạn trong dãy, nếu đoạn chỉ có 1 phần tử thì dãy đã được sắp xếp, ngược lại ta chọn một phần tử x trong đoạn để làm chốt, mọi phần tử nhỏ hơn chốt được xếp vào vị trí trước chốt, mọi phần tử lớn hơn chốt được sắp xếp vào vị trí đứng sau chốt

- Sau phép hoán chuyển như vậy thì đoạn đang xét được chia làm hai đoạn

mà mọi phần tử trong phần đầu của đoạn đều nhỏ hơn hoặc bằng chốt và mọi phần tử sau của đoạn đều lớn hơn hoặc bằng chốt

- Tiếp tục sắp kiểu như vậy với 2 đoạn con ta sẽ được đoạn đã cho được sắp xếp theo chiều tăng dần

Ý tưởng của thuật toán được mô tả cụ thể như sau:

Giả sử phải sắp xếp đoạn có chỉ số từ L đến H:

- Chọn x là một phần tử ngẫu nhiên trong đoạn L H ( có thể chọn x là phần

tử ở giữa đoạn, nghĩa là x=a[(L+H) div 2])

- Cho i chạy từ L sang phải, j chạy từ H sang trái; nếu phát hiện một cặp ngược thứ tự: i≤j và a[i]≥ x≥a[j] thì đổi chỗ hai phần tử đó; cho đến khi i>j lúc

đó dãy ở tình trạng: các phần tử đoạn L i≤x; các phần tử đoạn j H≥x

- Tiếp tục sắp xếp như vậy với đoạn L j và i H

Thủ tục Quicksort(L,H) sau dùng để sắp xếp đoạn từ L tới H Để sắp xếp dãy số

ta gọi Quicksort(1,n)

Procedure Quicksort (L,H:longint);

Var i,j: longint;

X,tg: longint;

Begin

Repeat

While a[i]<x do inc (i);

Trang 5

While a[j]>x do dec(j);

I<=j then

Begin

Inc(i); Dec(j);

End;

Until i>j;

If L<j then quicksort(L,j);

If i<H then quicksort(i,H);

End;

Thuật toán có độ phức tạp:

- Thời gian thực hiện cỡ O(nlogn) trong trường hợp tốt nhất

- Thời gian thực hiện cỡ O(n2) trong trường hợp xấu nhất (hai đoạn được chia thành 1 đoạn n-1 và 1 đoạn là 1 phần tử) Khả năng để xảy ra trường hợp này là rất ít, còn nếu chọn chốt ngẫu nhiên hầu như sẽ không xảy ra [1]

2.1.3 Thuật toán sắp xếp bằng đếm phân phối

Ví dụ bài toán: Cho dãy gồm N số nguyên tử a[1], a[2]….đến a[n] là các số

nguyên nằm trong đoạn từ 0 đến K, ta có thuật toán như sau:

- Xây dựng dãy b[0], b[1],…b[k], trong đó b[V] là số lần xuất hiện của khóa V trong dãy

For v:=0 to k do b[v] :=0;

For i:=1 to n do b[a[i]]:=b[a[i]]+1;

- Ví dụ: Với dãy gồm 8 phần tử có dãy khoá bằng 1,0,3,4,1,3,0,3 ta có:

Dãy số sau khi được sắp xếp: 0,0,1,1,3,3,3,4

Thuật toán có độ phức tạp: thời gian thực hiện là O(max(N,K)) [1]

2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm

- Khi tham gia dạy đội tuyển nhiều năm tại trường THPT Tĩnh Gia 1 tôi nhận thấy học sinh còn rất lung túng trong việc áp dụng thuật toán sắp xếp để giải quyết yêu cầu của bài toán

Trang 6

- Một số vấn đề học sinh hay gặp phải là: khi nào cần dùng thuật toán sắp xếp cho bài và áp dụng thuật toán sắp xếp nào để thuật toán của bài được tối ưu nhất với tất cả các bộ test có dữ liệu lớn nhỏ khác nhau

2.3 Các giải pháp sử dụng để giải quyết vấn đề

2.3.1 Một số bài tập áp dụng thuật toán sắp xếp nổi bọt

Bài tập 1: PHÂN SỐ

Cho dãy phân số F(N) trong đoạn [0,1], với mẫu số không vượt quá số nguyên dương N cho trước (1<N≤100)

Ví dụ: tập F(5): 0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1

Sắp xếp các phân số trong tập F(N) theo thứ tự tăng dần, đưa ra phân số

thứ K trong dãy F(N) [2]

4

Ý tưởng: Vì N nhỏ (không quá 100) nên có thể làm trực tiếp như sau:

- Sử dụng hai vòng lặp lông nhau để liệt kê hết tất cả các phân số, rồi tối giản để cho vào tập F(N)

- Tiến hành sắp xếp phân số

- Loại bỏ các phân số trùng nhau

- Đưa ra phân số thứ k

Chương trình tham khảo:

var n,k: longint; t,m: array[0 100000] of longint;

f,f1: text; dem: longint; i,j,d: longint;

function MaxDivisor(a: longint; b: longint): longint;

begin

while a<>b do

if a> b then a:=a-b else b:=b-a;

MaxDivisor:=b;

end;

Trang 7

procedure Toigian;

begin

for i:=1 to d-1 do

begin

t[i]:=t[i] div MaxDivisor(t[i],m[i]); m[i]:=m[i] div MaxDivisor(t[i],m[i]); end;

end;

procedure Sapxep;

var tmp,mmp: longint;

begin

for i:=1 to d-2 do

for j:=d-1 downto i+1 do

if (t[i]/m[i]) > (t[j]/m[j]) then begin

tmp:=t[i];t[i]:=t[j];t[j]:=tmp;

mmp:=m[i];m[i]:=m[j];m[j]:=mmp; end;

end;

begin

assign(f,' PHANSO.INP'); reset(f); readln(f,n,k); close(f);

t[0]:=0; m[0]:=1; d:=1;

for i:=2 to n do

for j:=1 to i-1 do

begin

t[d]:=j; m[d]:=i; d:=d+1;

Trang 8

end;

t[d]:=1; m[d]:=1;

Toigian;

Sapxep;

i:=0; dem:=1;

while (dem<k) and (i<d) do

begin

if (t[i]/m[i]) <> (t[i+1]/m[i+1]) then dem:=dem+1; i:=i+1;

end;

assign(f1,' PHANSO.OUT'); rewrite(f1);

writeln(f1,t[i]); writeln(f1,m[i]);

close(f1);

end

Trang 9

Bài tập 2: BAO PHỦ TRỤC

Trong giờ Hình học 10, thầy giáo biểu diễn N ( N≤104) đoạn thẳng trên một trục số, với các điểm đầu xi và độ dài di (|xi|,di là những số nguyên không vượt quá 109)

Yêu cầu: Hãy giúp thầy giáo tính xem tổng độ dài trục số mà N đoạn thẳng

đó che phủ lên

Dữ liệu vào: Vào từ file văn bản BAI2.INP:

- Dòng đầu chứa số nguyên dương N.

- N dòng tiếp theo, mỗi dòng chứa hai số nguyên xi và di.

Kết quả: Ghi ra file văn bản BAI2.OUT một số nguyên dương duy nhất là

kết quả của bài toán [2]

3

5 10

0 6 -100 10

25

Ý tưởng:

- Sắp xếp các đoạn số theo điểm đầu xi, sau đó duyệt lần lượt từng đoạn một

để tính tổng độ dài bị phủ

- Giả sử các đoạn (x1,d1), (x2,d2),… ,(xn,dn) ta sẽ sắp xếp tăng dần theo xi

Chương trình tham khảo:

var f,f1: text; n: integer;

x,d: array[1 10000] of longint;

i,j,tmp: longint;

kq,p: longint;

procedure Sapxep;

Trang 10

var tmp: longint;

begin

for i:=1 to n-1 do

for j:=n downto i+1 do

if x[i]>x[j] then begin

tmp:=x[i]; x[i]:=x[j]; x[j]:=tmp; tmp:=d[i]; d[i]:=d[j]; d[j]:=tmp; end;

end;

begin

assign(f,'BAI2.INP'); reset(f);

readln(f,n);

for i:=1 to n do readln(f,x[i],d[i]); close(f);

Sapxep;

kq:=d[1];

p:=x[1]+d[1];

for i:=2 to n do

if p<x[i] then begin

kq:=kq+d[i];

p:=x[i]+d[i];

end

else

if p<x[i]+d[i] then begin kq:=kq+x[i]+d[i]-p; p:=x[i]+d[i];

Trang 11

end;

assign(f1,'BAI2.OUT'); rewrite(f1);

writeln(f1,kq); close(f1);

end

2.3.2 Một số bài tập áp dụng thuật toán sắp xếp nhanh

Bài tập 3 DÃY CON ZERO

Cho dãy gồm N (N10000) số nguyên a1,a2,…an (|ai|109)

Yêu cầu: Hãy cho biết dãy con liên tiếp dài nhất trong dãy N có tổng số phần tử là 0 [2]

13

0 3 -2 -1 -3 5 -2 8 4 -4 0 0 0

0 3 -2 -1 3 5 -2

Ý Tưởng:

- Bước 1: xây dựng mảng S:

s[0]=0; s[1]=a[1]; …

s[i]=a[1]+a[2]+….a[i-1]+a[i], s[n]= a[1]+a[2]+….a[i-1]+a[i]

nếu đoạn con liên tiếp từ i đến j có tổng bằng 0 thì S[i-1]=S[j]

- Bước 2: Dễ dàng tìm dãy con liên tiếp có tổng bằng 0 nếu dãy S được sắp

xếp

Chương trình tham khảo:

var n,i,j: longint;t,s,a: array[0 10000] of longint;

tmp,max,luud,luuc: longint;

procedure QSort(l: longint; h: longint);

var x: longint;

begin

i:=l; j:=h;

x:=t[(l+h) div 2];

repeat

while t[i]<x do inc(i);

Trang 12

while t[j]>x do dec(j);

if i<= j then begin

tmp:=t[i]; t[i]:=t[j]; t[j]:=tmp; tmp:=s[i]; s[i]:=s[j]; s[j]:=tmp; inc(i); dec(j);

end;

until i>j;

If l<j then QSort(l,j);

if i<h then QSort(i,h);

end;

procedure Input;

var f: text;

begin

assign(f,'ZERO.INP'); reset(f);

readln(f,n);

for i:=1 to n do

begin

read(f,a[i]); s[i]:=i;

end;

s[0]:=0; close(f);

end;

procedure Xuly;

begin

t[0]:=0;

for i:=1 to n do

t[i]:=t[i-1]+a[i];

QSort(1,n);

Trang 13

max:=0;luud:=0; luuc:=0;

for i:=0 to n-1 do

for j:=n downto i+1 do begin

if t[i]=t[j] then

begin

tmp:=abs(s[i]-s[j])+1;

if tmp>max then begin

max:=tmp;

if s[j]<s[i] then begin

luud:=s[j]; luuc:=s[i]; end else begin

luud:=s[i]; luuc:=s[j]; end; end; end; end;

end;

procedure Output;

var f1: text;

begin

assign(f1,'ZERO.OUT'); rewrite(f1); for i:=luud+1 to luuc do write(f1,a[i],' '); close(f1);

end;

begin

Input; Xuly; Output;

end

Bài tập 4 Ghép số lớn

Trang 14

Vaxia đã viết được một số lớn trên một cuộn giấy dài và muốn khoe với anh trai Petia về thành quả vừa đạt được Tuy nhiên, khi Vaxia vừa ra khỏi phòng để gọi anh trai thì cô em Kachia chạy vào phòng và xé rách cuộn giấy thành một số mảnh Kết quả là trên mỗi mảnh có một hoặc vài kí số theo thứ tự đã viết Bây giờ Vaxia không thể nhớ chính xác mình đã viết số gì Vaxia chỉ nhớ rằng đó là một số rất lớn Để làm hài lòng cậu em trai, Petia quyết định truy tìm số nào là lớn nhất mà Vaxia đã có thể viết lên cuộn giây trước khi bị xé Bạn hãy giúp Petia làm việc này

Dữ liệu vào:

Gồm nhiều dòng mỗi dòng ghi một dãy kí số Số dòng không vượt quá

1000 Mỗi dòng ghi từ 1 đến 100 kí số Bảo đảm rằng có ít nhất một dòng mà kí

số đầu tiên khác 0

Dữ liệu ra:

Ghi ra số lớn nhất đã có thể viết trên cuộn giấy trước khi bị xé rách [3]

Ví dụ

Bai4.inp Bai4.out 2

20 004 66

66220004

* Ý tưởng:

- Lưu các số dưới dạng mảng kiểu xâu

- Thực hiện sắp xếp mảng theo thứ tự tăng dần theo tiêu chí sắp xếp là phần tử s[i] đứng trước phần tử s[j] khi (s[i] ghép với s[j]) > (s[j] ghép với s[i])

Chương trình tham khảo

var s: array[0 1000] of string;

i,n,j: word;

procedure qsort(L,H: word);

var tg,k:string;

Trang 15

if l>=h then exit;

i:=l; j:=h;

tg:=s[(l+h) div 2];

repeat

while tg+s[i]<s[i]+tg do inc(i);

while tg+s[j]>s[j]+tg do dec(j);

if i<=j then

begin

if i<j then begin

k:=s[i];

s[i]:=s[j];

s[j]:=k;

end;

inc(i);dec(j);

end;

until i>j;

Qsort(l,j);Qsort(i,h);

end;

begin

s[0]:='0'; n:=0;

while s[n]<>'' do

begin

inc(n);

readln(s[n]);

end;

qsort(1,n-1);

for i:=1 to n-1 do write(s[i]);

readln;

Trang 16

Bài tập 5 Đếm xâu con

Đếm số lượng xâu con liên tiếp khác nhau nhận được từ xâu s

Ví dụ: S = 'abab' có 7 xâu con là: a, b, ab, ba, aba,bab,abab [2]

* Ý tưởng:

- Lưu các xâu con có độ dài i (với i từ 1 đến length(s)) vào một mảng

- Sau đó sắp xếp mảng tăng dần theo độ dài các xâu con rồi thực hiện đếm

2.3.3 Một số bài tập áp dụng thuật toán sắp xếp phân phối

Bài tập 6: Phần tử xuất hiện nhiều nhất

Viết chương trình nhập từ bàn phím số nguyên dương N (0<N≤500) và các phần

tử của mảng 1 chiều a(n) có các giá trị nguyên dương (0<ai<100)

Yêu cầu: Hãy cho biết giá trị xuất hiện nhiều nhất trong A và xuất hiện bao

nhiêu lần?

ví dụ: a(16)={1,2,3,5,4,5,6,5,6,7,1,6,5,5,8,9} thì phần tử có giá trị bằng 5 là nhiều nhất số lượng phần tử này là 5

Ý tưởng thuật toán:

- Khỏi tạo mảng B ban đầu tất cả các phần tử đêu bằng 0

- Các phần tử B[x] là số lượng các phần tử có giá trị a[i]

- Duyệt mảng B tìm chỉ số phần tử lớn nhất

Chương trình tham khảo:

Var N:integer;

A:array[1 1000] of byte;

B:array[1 1000] of byte; slmax,i,csln:integer;

Begin

Writeln('nhap n= '); readln(n);

For i:=1 to n do

Begin

Write('a[',i,']= ');

Trang 17

End;

Fillchar(b,sizeof(b),0);

For i:=1 to N do inc(b[a[i]));

Slmax:=0;

For i:=1 to max do

If b[i]>slmax then

Begin

slmax:=b[j];

csln:=i;

End;

Writeln('so', csln,' co tan xuat xuat hien nhieu nhat ', b[csln]);

Readln;

End

Bài tập 7: Số phần tử khác nhau

Nhập vào số nguyên dương N (N≤103) và dãy số a1, a2…an Hãy cho biết

có bao nhiêu phần tử khác nhau trong dãy trên

Ý tưởng thuật toán:

- Khởi tạo mảng B đánh chỉ số từ 1 đến 32000 Giá trị các phần tử trong B có giá trị ban đầu bằng 0

- Duyệt mảng A ban đầu, đếm số lượng các phần tử a[i] giống nhau lưu vào mảng B là phần tử b[a[i]]

- Đếm các phần tử trong mảng B khác 0 chính là số phần tử khác nhau của dãy ban đầu

2.4 Hiệu quả của đề tài

- Qua nhiều năm trực tiếp dạy bồi dưỡng học sinh giỏi tại trường THPT Tĩnh

Gia 1 tôi đã hệ thống và tổng hợp lại một số bài tập có sử dụng thuật toán sắp xếp Tôi đã cho học sinh bồi dưỡng học và thực hành các thuật toán sắp xếp khác nhau và các em đã áp dụng để giải quyết được bài toán Đối với từng yêu cầu và dữ liệu của đề bài các em đã biết nên sử dụng thuật toán sắp xếp nào phù

Ngày đăng: 25/05/2021, 20:00

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w