Tải bản đầy đủ (.doc) (21 trang)

Hướng dẫn học sinh rèn luyện ký năng giải các bài toán về dãy con liên tiếp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (151.08 KB, 21 trang )

MỤC LỤC
1. Mở đầu………………………………………………………………………….1
1.1. Lý do chọn đề tài…………………………………………………………...1
1.2. Mục đich nghiên cứu……………………………………………………….1
1.3. Đối tượng nghiên cứu………………………………………………………1
1.4. Phương pháp nghiên cứu…………………………………………………...1
2. Nội dung sáng kiến kinh nghiệm…………………………………………….2
2.1. Cơ sở lí luận của sáng kiến kinh nghiệm…………………………………..2
2.2. Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm……………...2
2.3. Các giải pháp đã sử dụng để giải quyết vấn đề……………….....................3
2.3.1 Cung cấp lý thuyết về chuyên đề dãy con liên tiếp…..…………….....3
2.3.2 Viết chương trình cho 4 bài tập cơ bản…….........................................4
2.3.3 Làm các bài tập thực tế để vận dụng, cải tiến, hiệu chỉnh và nâng cấp
chương trình ……………………………………………………………………8
2.3.4 Giao bài tập về nhà…………………………………………………..18
2.4. Hiệu quả của sáng kiến kinh nghiệm đối với hoạt động giáo dục, với bản
thân, đồng nghiệp và nhà trường…………………………………………………..19
3. Kết luận, kiến nghị.........................................................................................20


1. Mở đầu
1.1. Lý do chọn đề tài
Trong chương trình Tin học lớp 11, nội dung kiến thức về mảng một chiều trang bị
cho học sinh chỉ bao gồm 2 tiết lí thuyết và 1 tiêt bài tập và 4 tiết thực hành. Vì vậy,
lượng kiến thức và thời lượng đó đó chưa đủ để học sinh có thể vận dụng vào giải
các bài tập liên quan đến các dãy con liên tiếp khi biểu diễn dãy bằng mảng một
chiều. Rèn luyện tư duy , kỹ năng và tác phong lập trình có vai trò đặc biệt trong
khi bỗi dưỡng học sinh giỏi môn tin học ở trường phổ thông. Hiệu quả của việc
rèn luyện tư duy, kỹ năng và tác phong lập trình là động lực giúp học sinh nắm
vững kiến thức, phát triển tư duy, hình thành kỹ năng và kỹ xảo. T ừ đó có khả
năng thích ứng khi đứng trước một vấn đề cần giải quyết. Học sinh cũng thấy được


mỗi thuật toán như là một quá trình suy luận, tư duy của học sinh mà phương pháp
tìm thuật toán không chỉ phụ thuộc vào đặc điểm của bài toán mà còn phụ thuộc tố
chất tâm lý của bản thân người xây dựng thuật toán.
Thực tế cho thấy có những học sinh có tố chất tốt, xong do không nắm vững được
khái niệm dãy con mà đề bài đưa ra và cách thức để bước đầu có thể xử lí bài toán
thì cũng không giải quyết được bài toán. Nhưng có những học sinh chỉ có tố chất
khá, xong nắm vững được khái niệm và quy luật của dãy con, thêm vào đó một
niềm đam mê môn học thì các em hoàn toàn vẫn có thể đạt được hiệu quả cao khi
giải quyết các bài toán liên quan đến dãy con liên tiếp. Vì lí do đó nên tôi chọn đề
tài: “Hướng dẫn học sinh rèn luyện kỹ năng giải các bài toán về dãy con liên
tiếp” để nghiên cứu.
1.2. Mục đích nghiên cứu
Nghiên cứu một số vấn đề lý thuyết và thực tiễn việc rèn luyện cho học sinh
các kỹ năng giải các bài toán về dãy con liên tiếp nhằm bồi dưỡng năng lực cũng
như kỹ năng lập trình, góp phần nâng cao chất lượng bồi dưỡng học sinh giỏi môn
Tin học ở trường phổ thông Hoằng Hóa 3.
1.3. Đối tượng nghiên cứu
Đối tượng nghiên cứu: kỹ năng giải các bài toán về dãy con liên tiếp đối với môn
tin học 11 của học sinh THPT.
Khách thể nghiên cứu: Học sinh thuộc đội tuyển học sinh giỏi môn Tin học của
trường THPT Hoằng Hóa 3
1.4. Phương pháp nghiên cứu
- Phương pháp nghiên cứu lý luận: Nghiên cứu các tài liệu, sách báo.
- Phương pháp điều tra thực tiễn: Quan sát việc học của học sinh trong quá trình
khai thác các bài tập sách giáo khoa, sách bài tập và các đề thi học sinh giỏi.
- Phương pháp thực nghiệm sư phạm
Trang

2



2. Nội dung sáng kiến kinh nghiệm
2.1. Cơ sở lí luận của sáng kiến kinh nghiệm
- Cơ sở tâm lý học:

+ Đặc điểm nhận thức của học sinh đối với môn Tin học:
Đối với khối THPT, hiện nay phần lớn học sinh coi bộ môn Tin học là môn học
phụ, không quan tâm cho lắm, vẫn còn có một vài học sinh có hứng thú với môn
Tin học. Từ số lượng ít ỏi đó vẫn có cơ hội để người giáo viên tìm ra các học sinh
cho đội tuyển học sinh giỏi của mình.
+ Tư duy của học sinh:

Thông thường những học sinh có kỹ năng lập trình khá, giỏi là những em có kiến
thức Toán học khá, giỏi, xong điều ngược lại thì chưa hẳn, lý do rất đơn giản là khả
năng vận dụng kiến thức vào để giải quyết vấn đề khi giải quyết bài toán Tin học.
Chẳng hạn, khi học giải bài tập môn toán các em có thể học theo dạng 1, dạng 2…
nhưng trong tin học thì một bài toán có thể là sự kết hợp của nhiều bài toán cơ bản
khác nhau.
Ở các em học sinh khối THPT thì môn lập trình Pascal các em bước đã làm
quen nhưng không chú trọng nên khả năng tư duy vẫn còn hạn chế nên việc phân
tích để hiểu được bản chất của vấn đề là rất khó.
2.2. Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm
- Thực trạng công tác bồi dưỡng học sinh giỏi môn Tin học hiện nay.

Thực tế đa số học sinh rất lúng túng về phương pháp cho loại toán này bởi vì trong
sách giáo khoa hay sách bài tập không có nhiều bài tập loại này nhưng lại có trong
đề thi học sinh giỏi những năm gần đây khiến cho học sinh rất bối rối về phương
pháp. Một số học sinh tham khảo một số code về các bài toán liên quan đến dãy
con trên mạng nhưng học sinh cũng khó hiểu và dẫn đến có thói quen lập trình thụ
động, không tự nhiên. Điều đó làm giảm đi hứng thú với môn học.

Qua những năm gần đây khi bồi dưỡng học sinh giỏi môn Tin học tôi nhận
thấy mảng kiến thức về dãy con liên tiếp là loại bài tập khá thú vị. Do đó tôi lựa
chọn đề tài này để nghiên cứu và trình bày. Bởi việc giúp các em tìm ra các cách
giải cho loại bài tập này giúp các em rất tốt trong quá trình học và rèn luyện kỹ
năng lập trình.
- Những thuận lợi và khó khăn:

+ Thuận lợi:
- Công tác bồi dưỡng học sinh giỏi hiện nay đối với môn Tin học đã được nhà
trường quan tâm chỉ đạo sát sao đặc biệt là đã có những phần thưởng có tính khích
lệ đối với giáo viên và học sinh hơn trước.
+ Khó khăn:

- Môn tin học ít có cơ hội chọn được học sinh tốt nhất.
- Phụ huynh học sinh cũng không thích cho con em mình vào đội tuyển mon
Tin học vì sợ ảnh hưởng đến việc học và ôn thi Đại học.
2.3. Các giải pháp đã sử dụng để giải quyết vấn đề
Trang

3


2.3.1 Cung cấp lý thuyết về chuyên đề dãy con liên tiếp
- Đưa ra khái niệm dãy con: Dãy con là dãy các phần tử liên tục thuộc một dãy
cho trước thỏa mãn một tính chất nào đó (ở đây ta cần hướng dẫn cho học sinh là
dãy ta đang xét được lưu dưới dạng mảng một chiều). Tuy nhiên cần lưu ý với học
sinh là cần phải đọc kỹ đề khi đề bài yêu cầu xác định một dãy con nào đó vì có thể
đề bài đưa ra yêu cầu đưa ra một dãy con liên tiếp theo thứ tự xuất hiện (tức là
không liền kề nnhau).
- Để quản lý dãy con ta cần: một chỉ số đầu(chỉ nơi bắt đầu dãy con) và độ dài của

dãy hoặc chỉ số đầu và chỉ số cuối (chỉ nơi kết thúc dãy con).
- Dãy con có thể có 1, 2, … N phần tử (tuỳ vào định nghĩa dãy con và yêu cầu đề
bài). Nếu dãy mẹ có N phần tử thì ta có 2n dãy con.
- Để duyệt qua tất cả các dãy con của một dãy gồm n số ta dùng thuật toán vét cạn
gồm 3 vòng For như sau:
For i:=1 to N do
{1}
For j:=1 to N-i+1 do
{2}
For k:=j to i+j-1 do
{3}
(xử lý dãy con bắt đầu từ vị trí j đến vị trí i+j-1); {4}
Giải thích:
{1} Vòng for 1: Cho biết độ dài của dãy con có i phần tử;
{2} Vòng for 2: Cho biết dãy con bắt đầu từ vị trí j, vậy vị trí bắt đầu của dãy con
cuối cùng có độ dài i sẽ là n-i+1;
{3} Vòng for 3: Dùng để duyệt qua các phần tử của dãy con bắt đầu từ vị trí đầu là
j đến vị trí cuối là i+j-1 để xử lý.
{4} Các thao tác xử lý có thể là: Tính tổng của dãy con; Kiểm tra tính tăng, giảm;
Kiểm tra tính đối xứng; ….
* Nếu dãy con đang xét cần lưu lại thì: Lưu lại độ dài, chỉ số đầu dãy. Xác
định lại độ dài, chỉ số đầu của dãy mới.
* Nếu dãy con đang xét không cần lưu thì: Xác định lại độ dài, chỉ số đầu
của dãy mới.
Khi dạy chuyên đề này ta có thể rèn luyện thêm cho học sinh cách viết và sử dụng
các chương trình con, để các chương trình con này tham gia vào nhiệm vụ xử lý ở
phần xử lý {4}, ví dụ chương trình con kiểm tra tính đối xứng của đoạn con từ j
đến j+i-1, chương trình con kiểm tra tính tăng, giảm của đoạn con, chương trình
con kiểm tra xem đoạn con đó có lập thành cấp số cộng hay không, …


Trang

4


2.3.2 Viết chương trình cho 4 bài tập cơ bản
Ở đây tôi đưa ra 4 loại bài tập cơ bản này để học sinh hiểu cách áp dụng lý thuyết
về dãy con đã cung cấp ở phần trên, với 4 bài tập cơ bản này giáo viên chưa cần
thiết đòi hỏi chương trình của học sinh làm ra phải chạy được bao nhiêu test mà chỉ
cần giải đúng được một vài trường hợp test nhỏ là được. Nhưng yêu cầu đặt ra với
học sinh là phải làm thành thạo được 4 bài toán cơ bản này thì mới có đủ kiến thức
và kỹ năng để xử lý các bài dãy con khác một cách tốt nhất có thể.
Bài cơ bản 1
Cho dãy A gồm N số nguyên. Viết chương trình in ra các dãy con liên tiếp gồm 1
phần tử, 2 phần tử, ... gồm N phần tử của dãy đã cho (dãy con liên tiếp là dãy gồm
một số phần tử liên tiếp của dãy đã cho có thể gồm 1 hoặc nhiều phần tử, bản thân
dãy đã cho cũng là 1 dãy con bằng có số phần tử bằng chính nó)
VD: N=6
Dãy A: 1 2 3 4 5 6
In ra:
Dc1: 1
Dc2: 2
Dc3: 3
Dc4: 4
Dc5: 5
Dc6: 6
Dc7: 1 2
Dc8: 2 3
Dc9 3 4
Dc10 4 5

Dc11 5 6
Dc12 1 2 3
Dc13 2 3 4
Dc14 3 4 5
Dc15 4 5 6
Dc16 1 2 3 4
Dc17 2 3 4 5
Dc18 3 4 5 6
Dc19 1 2 3 4 5
Dc20 2 3 4 5 6
Dc21 1 2 3 4 5 6
Với bài tập này học sinh chỉ cần vận dụng lý thuyết đã được cung cấp để giải quyết,
mục đích của bài tập này là để học sinh đưa ra được cũng như thấy được hình ảnh
cụ thể các dãy con của một dãy số cho trước.
Chương trình tham khảo như sau:
Trang

5


CONST NMAX=100;
VAR A: ARRAY[1..NMAX] OF INTEGER;
N,I,J,T: INTEGER;
BEGIN
WRITELN('NHAP N= ');
READLN(N);
FOR I:=1 TO N DO
BEGIN
WRITE('NHAP PHAN TU THU ',I);
READLN(A[I]);

END;
FOR I:=1 TO N DO
FOR J:=1 TO N-I+1 DO {DUET CAC DAY CON CO DO DAI I BAT DAU
TU J}
BEGIN
FOR T:= J TO J+I-1 DO WRITE(A[T],' ');
WRITELN;
END;
READLN;
END.
Bài cơ bản 2
Cho dãy A gồm N số nguyên. Viết chương trình in ra các dãy con liên tiếp gồm 1
phần tử, 2 phần tử, ... gồm N phần tử của dãy đã cho (dãy con liên tiếp là dãy gồm
một số phần tử liên tiếp của dãy đã cho có thể gồm 1 hoặc nhiều phần tử, bản thân
dãy đã cho cũng là 1 dãy con bằng có số phần tử bằng chính nó)
VD: N=6
Dãy A: 1 2 3 4 5 6
In ra:
Dc1: 1 2 3 4 5 6
Dc2: 1 2 3 4 5
Dc3: 2 3 4 5 6
Dc4: 1 2 3 4
Dc5: 2 3 4 5
Dc6: 3 4 5 6
Dc7: 1 2 3
Dc8: 2 3 4
Dc9 3 4 5
Dc10 4 5 6
Dc11 1 2
Dc12 2 3

Trang

6


Dc13 3 4
Dc14 4 5
Dc15 5 6
Dc16 1
Dc17 2
Dc18 3
Dc19 4
Dc20 5
Dc21 6
Mục đích của bài tập 2 này là rèn luyện thêm kỹ năng chuyển đổi giữa câu lệnh For
tiến và For lùiviệc làm này có lợi khi giáo viên đưa ra yêu cầu tìm một dãy con
ngắn nhất hoặc dài nhất thỏa mãn một điều kiện nào đó, khi đó học sinh sẽ biết nên
chọn câu lệnh for nào để khi tìm thấy một dãy con như vậy thì thoát luôn không cần
tìm tiếp.
Chương trình tham khảo như sau:
CONST NMAX=100;
VAR A: ARRAY[1..NMAX] OF INTEGER;
N,I,J,T: INTEGER;
BEGIN
WRITELN('NHAP N= ');
READLN(N);
FOR I:=1 TO N DO
BEGIN
WRITE('NHAP PHAN TU THU ',I);
READLN(A[I]);

END;
FOR I:=N DOWNTO 1 DO
FOR J:=1 TO N-I+1 DO
BEGIN
FOR T:= J TO J+I-1 DO WRITE(A[T],' ');
WRITELN;
END;
READLN;
END.
Bài cơ bản 3
Cho dãy A gồm N số nguyên. Viết chương trình in ra các dãy con liên tiếp của dãy
đã cho (dãy con liên tiếp là dãy gồm một số phần tử liên tiếp của dãy đã cho có thể
gồm 1 hoặc nhiều phần tử, bản thân dãy đã cho cũng là 1 dãy con bằng có số phần
tử bằng chính nó)
VD: N=6
Trang

7


Dãy A: 10 1 2 5 9 4
In ra:
Dc1: 10 1 2 5 9 4
Dc2: 10 1 2 5 9
Dc3: 10 1 2 5
Dc4: 10 1 2
Dc5: 10 1
Dc6: 10
Với bài tập này ta tập cho học sinh thói quen đọc kỹ đề bài và xem xét kỹ output
của bài toán để từ đó đưa ra những điều chỉnh trong cách duyệt để tìm đúng output,

vì đề bài cũng yêu cầu đưa ra các dãy con nhưng chỉ khác là các dãy con có độ dài
từ 1 đến N chỉ được đưa ra đúng một lần và các dãy con đó đều bắt đầu từ phần tử
thứ 1 của dãy.
Từ đó có thể tự phân tích được cách làm, nếu học sinh còn lúng túng giáo viên có
thể hướng dẫn học sinh để đưa ra nhận xét sau:
- Có N lần duyệt, vậy ta dùng biến i là biến duyệt số lần, với i chạy từ 1 đến N
- Với mỗi lần duyệt i, ta in ra các dãy con từ 1 đến N-i+1
Vậy khi đó chỉ cần có 2 vòng for là đủ để in ra các dãy con này, vậy so với thuật
toán vét cạn đã được giới thiệu ở phần lý thuyết thì ta bỏ bớt đi vòng lặp thứ 3.
Chương trình tham khảo như sau:
CONST NMAX=100;
VAR A: ARRAY[1..NMAX] OF INTEGER;
N,I,J,T: INTEGER;
BEGIN
WRITELN('NHAP N= ');
READLN(N);
FOR I:=1 TO N DO
BEGIN
WRITE('NHAP PHAN TU THU ',I);
READLN(A[I]);
END;
FOR I:=1 TO N DO
BEGIN
FOR J:=1 TO N-I+1 DO
WRITE(A[J],' ');
WRITELN;
END;
READLN;
END.
Trang


8


Tương tự như vậy giáo viên có thể thay đổi cách in các dãy con để học sinh rèn
luyện thêm kỹ năng, chẳng hạn thay đổi thành bài toán cơ bản 4 sau đây:
Bài cơ bản 4
Cho dãy A gồm N số nguyên. Viết chương trình in ra các dãy con liên tiếp của dãy
đã cho (dãy con liên tiếp là dãy gồm một số phần tử liên tiếp của dãy đã cho có thể
gồm 1 hoặc nhiều phần tử, bản thân dãy đã cho cũng là 1 dãy con bằng có số phần
tử bằng chính nó)
VD: N=6 ;Dãy A: 10 1 2 5 9 4
In ra:
Dc1: 10
Dc2: 10 1
Dc3: 10 1 2
Dc4: 10 1 2 5
Dc5: 10 1 2 5 9
Dc6: 10 1 2 5 9 4
Với bài này thì học sinh tự sửa lại chương trình của bài tâp cơ bản 3 ở trên là xong.
2.3.3 Làm các bài tập thực tế để vận dụng, cải tiến, hiệu chỉnh và nâng cấp
chương trình
Đối với phần này khi làm bài tập giáo viên có thể đưa ra 3 mức độ để học sinh rèn
luyện và nâng cao kỹ năng lập trình:
Mức độ 1: Yêu cầu học sinh cải tiến chương trình đã viết nếu có thể
Ở mức độ này giáo viên nên yêu cầu học sinh bám sát vào các đặc điểm của dữ
liệu, dữ kiện mà đê bài yêu cầu, tuy nhiên giáo viên chưa đặt ra yêu cầu là phải
chạy được nhiều test. Chỉ cần chạy được 1 đến 2 hoặc 3 test đúng là được.
Mức độ 2: Hướng dẫn học sinh sử dụng các kỹ thuật lập trình khác để nâng cấp
chương trình chạy được nhanh hơn (nhiều test hơn)

Ở mức độ này dựa vào vào các đặc điểm của dữ liệu, dữ kiện mà đê bài yêu cầu,
giáo viên có thể hướng dẫn thêm học sinh các kỹ thuật khác để giúp học sinh nâng
cấp chương trình nhưng chưa phải là chạy hết được các test. Chẳng hạn kỹ thuật
dùng biến định vị (lính canh), kỹ thuật trượt cửa sổ, kỹ thuật đặ cờ hiệu…
Mức độ 3: Tùy vào năng lực tiếp thu của học sinh giáo viên có thể hướng dẫn học
sinh sử dụng các kỹ thuật lập trình khác để xử lý các bộ test lớn của bài toán.
Chẳng hạn như quy hoạch động…
Dưới đây là một số bài tập tôi đã sử dụng để rèn luyện kỹ năng cho học sinh:
Bài tập 1: Cho một mảng số nguyên gồm n phần tử. Tìm dãy con gồm m phần tử
(m≤ n ≤ 1000) sao cho dãy con này có tổng lớn nhất. (Dãy con là dãy các phần tử
liên tiếp nhau trong mảng).
Ví dụ: nhập vào từ bàn phím
N=6
1 -3 2 -5 4 3
Trang

9


M=4
In ra màn hình: 2 -5 4 3
Khi làm bài tập này, dựa vào lý thuyết học sinh đã được cung cấp thuật toán vét
cạn:
For i:=1 to N do
{1}
For j:=1 to N-i+1 do
{2}
For k:=j to i+j-1 do
{3}
(xử lý dãy con bắt đầu từ vị trí j đến vị trí i+j-1); {4}

thì học sinh sẽ có nhận xét sau:
- Vì số phần tử của dãy con là m nên ta sẽ bỏ đi vòng lặp 1 mà thay i trong
vòng lặp 2 và 3 bằng m. Mỗi lần xử lý dãy con thì ta tính tổng dãy con đó và
so sánh để tìm ra tổng lớn nhất đồng thời lưu lại vị trí j của dãy con đó.
- Khi đó chỉ cần sử dụng 2 vòng lặp
For j:=1 to N-m+1 do
For k:=j to m+j-1 do
(xử lý dãy con bắt đầu từ vị trí j đến vị trí i+j-1);
Khi đó học sinh có thể viết chương trình như sau:
Type M1C=ARRAY[1..1000] Of Integer;
Var A:M1C;
n,m,i,j,k,vt:integer;
S,Max:longint;
Begin
Write('Nhap so phan tu cua mang: n= '); Readln(n);
For i:=1 To n Do
Begin
Write('a[',i,']='); Readln(a[i]);
End;
Write('Nhap so phan tu cua day con: m= '); Readln(m);
Max:=0; vt:=1;
For j:=1 To n-m+1 Do
Begin
{Tính tổng của dãy con thứ j}
S:=0;
For k:=j To j+m-1 Do S:=S+A[k];
If S>Max Then { Nếu dãy con tìm được có tổng lớn hơn dãy con trước}
Begin
Max:=S; {Thay tổng mới}
vt:=j;

{ Thay vị trí đầu tiên của dãy con mới }
End;
Trang 10


End;
Writeln('Day con co tong lon nhat la:');
For i:=vt To vt+m-1 Do Write(A[i]:5);
Readln;
End.
Sau khi đã viết được chương trình giáo viên có thể yêu cầu học sinh tự cải tiến
chương trình nếu có thể, nếu học sinh còn lúng túng thì giáo viên mới đưa ra nhận
xét để học sinh cải tiến chương trình của mình.
Hướng dẫn cải tiến chương trình: Giống như trong bài toán tìm giá trị lớn nhất
của dãy số, ban đầu ta giả sử Max = A[1], thì ở đây ta cũng giả sử tổng Max ban
đầu là tổng các phần tử từ 1 đến M, các lần sau ta chỉ tìm và so sánh tổng Max với
các dãy con bắt đầu từ vị trí thứ 2 trở đi, chương trình tham khảo như sau:
Type M1C=ARRAY[1..1000] Of Integer;
Var A : M1C;
n,m,i,j,k,vt:integer;
S,Max:longint;
Begin
Write('Nhap so phan tu cua mang: n= '); Readln(n);
For i:=1 To n Do
Begin
Write('a[',i,']='); Readln(a[i]);
End;
Write('Nhap so phan tu cua day con: m= '); Readln(m);
vt:=1; {Vị trí phần tử đầu tiên của dãy con}
{Giả sử m phần tử đầu tiên của mảng A là dãy con có tổng lớn nhất}

Max:=0;
For i:=1 To m Do Max:=Max+A[i];
{Tìm các dãy con khác}
For j:=2 To n-m+1 Do
Begin
{Tính tổng của dãy con thứ j}
S:=0;
For k:=j To j+m-1 Do S:=S+A[k];
If S>Max Then { Nếu dãy con tìm được có tổng lớn hơn dãy con trước thì}
Begin
Max:=S; { Thay tổng mới }
vt:=j;
{ Thay vị trí đầu tiên của dãy con mới }
End;
End;
Writeln('Day con co tong lon nhat la:');
Trang 11


For i:=vt To vt+m-1 Do Write(A[i]:5);
Readln;
End.
Khi chương trình đã chạy đúng được một vài test giáo viên có thể yêu cầu
học sinh sửa lại chương trình để thực hiện việc đọc dữ liệu từ tệp và ghi kết quả ra
tệp, chạy chương trình với N=1000 nếu có thể.
Bài tập 2:
Chia hết
Cho một dãy gồm N số nguyên dương A 1, A2, ..., AN. Hãy lấy ra K số liên
tiếp để tổng của chúng chia hết cho N với K bé nhất.
Dữ liệu: Đọc vào từ file văn bản DAY.INP:

• Dòng đầu ghi N.
• Dòng tiếp ghi các số A1, A2, ..., AN.
Kết quả: ghi ra file văn bản DAY.OUT gồm một dòng ghi giá trị K và chỉ số của số
hạng đầu tiên được lấy ra.
Giới hạn: N và các Ai ≤ 32767.
Ví dụ:
DAY.INP
DAY.OUT
5
24
12214
Khi làm bài tập này với thuật toán vét cạn để đưa ra các dãy con đã được cung cấp,
học sinh có thể viết được chương trình ở mức độ chưa chính xác như sau:
program Bt2;
Type m1c = array[1..10000] of integer;
Var a:m1c;
i, j, t,n, kmax,jmax:integer;
tong:longint;
thay:boolean;
f1,f2:text;
BEGIN
Assign(f1,'DAY.INP'); Reset(f1);
readln(f1,n);
for i:= 1 to n do Read(f1,a[i]);
Close(f1);
Assign(f2,'DAY.OUT'); Rewrite(f2);
{xu ly}
for i:=1 to N do
for j:=1 to N- i+1 do
begin

tong:=0;
for t:=j to j+i-1 do
Trang 12


tong:=tong+a[t];
if tong mod n =0 then
begin
kmax:=i;
jmax:=j;
end;
end;
Write(f2,kmax, ' ', jmax);
Close(f2);
END.
Chương trình trên cũng đưa ra được dãy con có tổng chia hết cho N nhưng không
phải là dãy con ngắn nhất (k nhỏ nhất). Do vậy ở đây giáo viên phải hướng dẫn
học sinh thêm kỹ thuật đặt cờ hiệu để thoát các vòng For khi tìm thấy dãy con đầu
tiên, ngắn nhất thõa mãn có tổng chia hết cho N. Chương trình tham khảo như sau:
program Bt2;
Type m1c = array[1..10000] of integer;
Var a:m1c;
i, j, t,n, kmax,jmax:integer;
tong:longint;
thay:boolean;
f1,f2:text;
BEGIN
Assign(f1,'DAY.INP'); Reset(f1);
readln(f1,n);
for i:= 1 to n do Read(f1,a[i]);

Close(f1);
Assign(f2,'DAY.OUT'); Rewrite(f2);
for i:=1 to N do
begin
thay:=false;
for j:=1 to N- i+1 do
begin
tong:=0;
for t:=j to j+i-1 do
tong:=tong+a[t];
if tong mod n =0 then
begin
kmax:=i;
jmax:=j;
thay:=true; end;
if thay then break;
end;
if thay then break;
end;
Write(f2,kmax, ' ', jmax);
Close(f2);
END.
Trang 13


Với bài này đề bài không cho giới hạn của N nên giáo viên cũng chưa cần yêu cầu
chương trình của học sinh phải chạy được nhiều test.
Bài tập 3: Đoạn con
Cho dãy số nguyên a1, a2,..., aN (|ai| < 109, N < 105). Một tập hợp khác rỗng các
số hạng liên tiếp {ai, ai+1,..., ak} (i ≤ k) gọi là một đoạn con của dãy đó. Với mỗi

đoạn con ta tính tổng tất cả các số hạng của nó.
Yêu cầu: Tìm giá trị lớn nhất trong số các tổng của các đoạn con của dãy đã cho.
Dữ liệu vào: cho trong file SUBSEQ.INP:
Dòng đầu chứa số N, dòng thứ i trong N dòng tiếp theo chứa số ai.
Dữ liệu ra: Ghi ra file SUBSEQ.OUT một số nguyên là giá trị tổng đoạn con lớn
nhất tìm được.
Ví dụ:
SUBSEQ.INP
SUBSEQ.OUT
7
8
1
-2
(Giải
thích:
-1
đoạn con tổng
4
lớn nhất là:
-1
4 – 1 + 5 = 8)
5
-2
(60% số test có N < 3000)
(Trích đề thi Học sinh giỏi tỉnh Ninh bình 2010-20111 Vòng 1)
Khi làm bài này, vận dụng thuật toán vét cạn để duyệt dãy con học sinh có thể viết
chương trình như sau:
Type m1c = array[1..100000] of longint;
Var a:m1c;
i, j, t,n :longint;

tong,kq:int64;
f1,f2:text;
BEGIN
Assign(f1,'SUBSEQ.INP'); Reset(f1);
readln(f1,n);
for i:= 1 to n do Readln(f1,a[i]);
Close(f1);
Assign(f2,'SUBSEQ.OUT'); Rewrite(f2);
{xu ly}
kq:=-200000000000000000;
for i:=1 to N do
for j:=1 to N- i+1 do
Trang 14


begin
tong:=0;
for t:=j to j+i-1 do
tong:=tong+a[t];
if tong > kq then
kq:=tong;
end;
Write(f2,kq);
Close(f2);
END.
Tuy nhiên gáo viên cần cho học sinh chạy một vài test sau đó thử chạy các test lớn
(theo đề bài N<105) sau đo chỉ ra cho học sinh thấy nêu dùng thuật toán vét cạn thì
các test lơn sẽ chạy quá lâu, từ đó hướng dẫn học sinh cải tiến thuật toán theo năng
lực của các em theo 2 mức độ:
Mức độ 1: Dựa vào kỹ thuật quy hoạch động, ta hướng dẫn cải tiến như sau:

- Dùng mảng một chiều B để lưu tổng các dãy con cơ bản của dãy, với B[i] là tổng
của i phần tử đầu tiên. Khi đó muốn tìm tổng của dãy con từ vị trí i đến vị trí j ta
chỉ việc lấy b[j]-b[i-1] là được (với i<=j<=N).
- Thay vì đọc dữ liệu vào mảng sau đó mới xử lý thì ta đọc từng số vào biến, cộng
dồn vào biến tong để lưu vào mảng tổng B
- Bổ sung thêm phần tử B[0] để làm mốc tính toán với B[0]=0, ví dụ muốn tính
tổng dãy con từ phần tử thứ 1 đến phần tử thứ 2 thì ta phải lấy B[2]-B[0].
- Vét cạn các khả năng để tìm dãy con có tổng lớn nhất bằng cách tìm hiệu các
B[j]-B[i-1] để so sánh với kq (giả sử là tổng lớn nhất cần tìm), với i chạy từ 1 đến
N , j chạy từ i đến N.
Chương trình tham khảo:
const nmax=round(1e5);
fi='subseq.inp';
fo='subseq.out';
var a:array[1..nmax] of longint;
b:array[0..nmax] of int64;
var f1,f2:text;
n,i,j,x,d:longint;
kq,tong:int64;
begin
assign(f1,fi);reset(f1);
assign(f2,fo);rewrite(f2);
readln(f1,n);
b[0]:=0;
for i:=1 to n do
begin
readln(f1,x);
Trang 15



tong:=tong+x;
b[i]:=tong;
end;
close(f1);
kq:=-20000000000000000;
for i:=1 to n do
for j:=i to n do
if b[j]-b[i-1]>kq then kq:=b[j]-b[i-1];
writeln(f2,kq);
close(f2);
end.
Mức độ 2: Sau khi cải tiến chương trình trên đã chạy được tương đối, nhưng với
test lớn thì chương trình vẫn chạy hơi chậm. Từ đó giáo viên có thể hướng dẫn học
sinh vận dụng thêm kỹ thuật tìm giá trị lớn nhất trên mảng B để so sánh với kết
quả, khi đó thay vì phải vét cạn tất cả các trường hợp trên mảng B bằng 2 vòng For
thì ta chỉ giải quyết trên một vòng For, đương nhiên là chương trình sẽ chạy nhanh
hơn và chạy hết được các test của bài này.
Cụ thể, ta cải tiến như sau:
- Ban đầu ta đặt Max:=B[N] {là tổng của toàn bộ dãy}, kq:=-200000000000000;
{giả sử kết quả là một số âm rất lớn}
- Cho i chạy từ N-1 về 0, tức là duyệt mảng B từ N-1 về 0 để tìm dãy con có tổng
lớn nhất, mỗi lần duyệt ta so sánh kq với Max-B[i] nếu kq < Max-B[i] thì cập nhật
lại kq = Max-B[i], đồng thời so sánh B[i] với Max nếu B[i]>Max thì cập nhật lại
Max=B[i]
Chương trình tham khảo như sau:
const nmax=round(1e5);
fi='subseq.inp';
fo='subseq.out';
var a:array[1..nmax] of longint;
b:array[0..nmax] of int64;

f1,f2:text;
n,i,j,x:longint;
max,tong,kq:int64;
begin
assign(f1,fi);reset(f1);
assign(f2,fo);rewrite(f2);
readln(f1,n);
b[0]:=0;
for i:=1 to n do
begin
Trang 16


readln(f1,x);
tong:=tong+x;
b[i]:=tong;
end;
close(f1);
max:=b[n];
kq:=-200000000000000;
for i:= n-1 downto 0 do
begin
if kqif b[i]>max then max:=b[i];
end;
writeln(f2,kq);
close(f2);
end.
Trên đây là một ví dụ cụ thể mà sau khi dùng thuật toán vét cạn để giải quyết
nhưng phải qua 2 lần cải tiến ta mới có được chương trình đáp ứng được yêu cầu

của đề bài.
Bài tập 4: Dãy số vòng tròn
Trên một vòng tròn người ta đánh dấu n vị trí. Các vị trí được đánh số thứ tự
từ 1 đến n theo chiều kim đồng hồ. Tại vị trí i người ta ghi số nguyên ai (i=1,2,...,n).
Cần tìm cách chọn ra dãy con gồm k số liên tiếp (0kim đồng hồ) để tổng các số hạng trong dãy con này là lớn nhất.
Dữ liệu: Vào từ file BAI4.INP:
Dòng đầu tiên ghi số nguyên dương n.

Các dòng tiếp theo ghi n số a1, a2,…, an

Kết quả: Ghi ra file BAI4.OUT:
• Dòng đầu tiên ghi giá trị tổng các số hạng của dãy tìm được
• Dòng thứ hai ghi hai số nguyên d và k cách nhau ít nhất một dấu trắng trong
đó d là chỉ số của số hạng đầu tiên của dãy (số hạng bên trái nhất) còn k là số lượng
các số hạng của dãy tìm được.
Giới hạn: |ai| ≤ 32000; ai ≠ 0; n ≤ 106; 0 < k < n.
Ví dụ:
BAI4.INP
BAI4.OUT
7
11
2 -4 1 -7 4 6 -1
54
Khi làm bài tập này ban đầu giáo viên nên hướng dẫn cho học sinh các cách
cơ bản sau để giải quyết bài toán này với các test nhỏ:
Trang 17


Cách 1: Nhân đôi mảng (dãy số ban đầu), sau đó dùng thuật toán vét cạn để thực

hiện việc tìm dãy con. Tuy nhiên ta thấy ngay được là chương trình chạy sẽ chậm.
Cách 2: Cải tiến thuật toán vét cạn để tìm dãy con có K phần tử thõa mãn đề bài
như sau:
- Gọi K là độ dài của dãy con cần tìm, vậy theo đề bài: k sẽ chạy từ 1 đến N-1
- Gọi i là vị trí bắt đầu các dãy con, nên i <=N, bởi vì khi i=N+1 thì dãy cần tìm có
thể lấy lại đoạn đã lấy. Vậy i sẽ hạy từ 1 đến N
+ Với mỗi dãy con đủ K phần tử từ vị trí i đến vị trí i+k-1 thì ta tính tổng t
như sau:
+ Cho j chạy từ i đến i+k-1 ta cộng vào tổng t số a[j] nếu j<=N ngược lại ta
cộng vào tổng t số a[j-n].
+ So sánh tổng t với biến Max nếu t > Max thì ta cập nhật lại Max, đồng thời
lưu lại giá trị K vào biến sl (độ dài dãy cần tìm) và chỉ số đầu của dãy vào biến vt.
- Sau khi duyệt xong ta sẽ tìm được vị trí của dãy con có độ dài K thõa mãn có
tổng lớn nhất, khi đó ta chỉ việc đưa ra giá trị biến Max, K, vt. Chương trình
tham khảo như sau:
const fi='bai4.inp';
fo='bai4.out';
var f1, f2:text;
n, i, j, max, t, vt, k, sl:longint;
a:array[1..1100000] of longint;
begin
assign(f1,fi);
reset(f1);
assign(f2,fo);
rewrite(f2);
readln(f1,n);
for i:=1 to n do read(f1,a[i]);
max:=-maxlongint;
for k:=n-1 downto 1 do
for i:=1 to n do

begin
t:=0;
for j:=i to i+k-1 do
if j<=n then t:=t+a[j] else t:=t+a[j-n];
if t>max then
begin max:=t;
sl:=k;
vt:=i; end;
end;
writeln(f2,max);
writeln(f2,vt,' ',sl);
close(f1); close(f2);
end.
Trang 18


Sau khi chạy chương trình với một số test giáo viên nên hướng dẫn học sinh tạo ra
một test với giá trị N=106 (giáo viên dùng hàm random để tạo test này, ghi các số
tạo được vào tệp đầu vào theo đề bài) để học sinh chạy thử xem thế nào? Và chỉ ra
bước tiếp theo ta nên cải tiến thuật toán theo hướng nào? Hướng dẫn học sinh dùng
kỹ thuật nào?
Tuy nhiên cũng cần phải thấy rằng phần đông học sinh trung học phổ thông
nếu thầy cô cố gắng hướng dẫn kỹ thuật quy hoạch động để chạy hết test bài này thì
cũng hơi khó khăn. Ở đây ta phải căn cứ vào năng lực của học sinh mình đến đâu
thì mới quyết định đưa ra phương án tiếp theo để học sinh rèn luyện kỹ năng.
Bài tập rèn luyện ở nhà:
2.3.4 Giao bài tập về nhà
BTVN 1: Dãy con
Cho một dãy số gồm N sốnguyên dương a1, a2, …,an , và số nguyên dương M.
Yêu cầu: tìm độ dài lớn nhất của dãy con chứa các phần tử liên tiếp của dãy mà các

phần tử đều chia hết cho M
Dữ liệu vào: Đọc từ file BAI2.INP có cấu trúc như sau:
Dòng 1: Ghi 2 số nguyên N ( 0Dòng 2: Ghi n số nguyên a1, a2, …, an (cách nhau bởi một dấu cách, |ai|<=109)
Kết quả: Ghi vào tệp BAI2.OUT có cấu trúc sau:
Dòng 1: ghi độ dài lớn nhất của dãy con chứa các phần tử liên tiếp của dãy mà các
phần tử đều chia hết cho M.
Dòng 2: ghi ước số chung lớn nhất của độ dài lớn nhất của dãy con và số 1000
Ví dụ:
BAI2.INP
BAI2.OUT
75
3
27 5 10 35 7 26
1
BTVN 2: Dãy con tăng dần
Một dãy số a1, a2, a3, .., an. được gọi là dãy tăng nếu a1<= a2<= a3<= …<= an
Cho một dãy số gồm tối đa n số (1<=n<=10000). Viết chương trình tìm chiều dài
dãy con liên tiếp tăng dài nhất trong dãy nói trên.
Dữ liệu vào: cho trong tệp ‘DAY.INP’ gồm:
- Dòng đầu ghi giá trị n
- n dòng tiếp theo gồm n số nguyên dương, các số này cách nhau ít nhất một khoagr
trắng.
Dữ liệu ra: Ghi vào tệp “DAY.OUT’ một số duy nhất là độ dài của dãy con liên tiếp
dài nhất tìm được.
Ví dụ:
DAY.INP
DAY.OUT
6
4

1 3 2 4 5 10
Trang 19


BTVN 3: ĐOẠN MAX
Cho chuỗi ký tự S gồm các chữ cái in hoa (A…Z) với độ dài không vượt quá 104.
Yêu cầu: Hãy tìm đoạn con các kí tự liên tiếp dài nhất sao cho không có kí tự nào
xuất hiện nhiều hơn một lần. Trong trường hợp có nhiều hơn một đoạn con có cùng
chiều dài dài nhất, hãy chỉ ra đoạn xuất hiện đâu tiên trong chuỗi S.
Dữ liệu: Vào từ văn bản DOANMAX.INP:
- Gồm một dòng duy nhất chứa chuỗi S.
Kết quả: Ghi ra file văn bản DOANMAX.OUT
- chỉ một dòng duy nhất chứa số nguyên P và L tương ứng là vị trí và chiệu dài
của đoạn con dài nhất tìm được.
Ví dụ:
DOANMAX.INP
DOANMAX.OUT
ABABCDAC
34
Lưu ý: Có 80% test có độ dài xâu không vượt quá 255.
Giải thích test ví dụ: Đoạn con dài nhất tìm được là ABCD có vị trí 3 và dộ dài 4
BTVN 4: Dãy con đối xứng dài nhất
Dữ liệu vào: từ tệp DCDX.inp dòng thứ nhất chứa số nguyên N, dòng 2 ghi N số
mỗi số ách nhay 1 dấu cách.
Dữ liệu ra: ghi vào tệp DCDX.out dãy con liên tiếp đối xứng dài nhất
Ví dụ:
BAI2.INP
BAI2.OUT
8
44344

12144344
BTVN 5: Dãy con lập thành cấp số cộng
Dữ liệu vào: từ tệp DCCSC.inp dòng thứ nhất chứa số nguyên N, dòng 2 ghi N số
mỗi số ách nhay 1 dấu cách
Dữ liệu ra: ghi vào tệp DCCSC.out dãy con liên tiếp lập thành cấp số cộng (tức
ai=ai-1 +d)
Ví dụ:
BAI2.INP
BAI2.OUT
8
456
12145621
2.4. Hiệu quả của sáng kiến kinh nghiệm đối với hoạt động giáo dục, với bản
thân, đồng nghiệp và nhà trường
Trong các năm học vừa qua với việc “Hướng dẫn học sinh rèn luyện kỹ
năng giải các bài toán về dãy con liên tiếp” như phần trên đã trình bày tôi đã thu
được những kết quả bước đầu đáng khích lệ. Dựa trên năng lực và ý thức chấp hành
của học sinh tôi đã phát huy được điểm mạnh của các em khi rèn luyện kỹ năng lập
trình, các em đã đạt được kết quả trong các kỳ thi học sinh giỏi. Kết quả của cách
làm đó dược các đồng nghiệp trong nhóm Tin học ghi nhận và đánh giá cao.
Trang 20


3. Kết luận, kiến nghị
- Một số kết luận:

Trong quá trình nghiên cứu tôi xin rút ra một số kết luận sau:
- Để bồi dưỡng học sinh giỏi đạt hiệu quả trước hết giáo viên phải có kỹ năng
thực hành và thiết kế kịch bản bồi dưỡng tốt.
- Thực sự tâm huyết với công việc bồi dưỡng học sinh giỏi.

- Giáo viên nên tham khảo thêm các đề thi học sinh giỏi của các tỉnh các năm
trước.
- Tham khảo nhiều sách báo tài liệu có liên quan, giao lưu học hỏi các bạn
đồng nghiệp có nhiều kinh nghiệm, các trường có bề dày thành tích.
- Giáo viên phải khơi dậy niềm say mê, hứng thú của học sinh đối với môn tin
học, luôn phối hợp với giáo viên chủ nhiệm và gia đình để tạo điều kiện tốt nhất
cho các em tham gia học tập.
- Kiến nghị:

- Đối với nhà trường BGH nên chú trọng hơn công tác khảo sát, lựa chọn học
sinh và phân bổ các đối tượng học sinh cho các môn để bồi dưỡng học sinh giỏi. Vì
gần như môn Tin học là môn được chỉ chọn được học sinh đội tuyển sau khi cac
môn tự nhiên khác đã chọn.
- Đối với các cấp cũng nên ra các dạng đề thi phong phú, phù hợp với khả năng
và trình độ của học sinh, không nên ra đề quá sức đối với học sinh.
XÁC NHẬN CỦA THỦ TRƯỞNG
ĐƠN VỊ

Thanh Hóa, ngày28 tháng 05 năm 2016
Tôi xin cam đoan đây là SKKN của mình viết,
không sao chép nội dung của người khác.
(Ký và ghi rõ họ tên)

Lê Văn Khánh

TÀI LIỆU THAM KHẢO
1. SGK tin học 11
- NXB Giáo dục Việt Nam
2. Sách bài tập tin học 11
- NXB Giáo dục Việt Nam

3. Một số tài liệu trên mạng Internet.
Trang 21



×