1. Trang chủ
  2. » Giáo án - Bài giảng

Chuyên đề bồi dưỡng học sinh giỏi: Cấu trúc dữ liệu heap và ứng dụng

21 2,7K 13
Tài liệu đã được kiểm tra trùng lặp

Đ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

Tiêu đề Chuyên đề bồi dưỡng học sinh giỏi: Cấu trúc dữ liệu heap và ứng dụng
Trường học Trường Trung Học Phổ Thông
Chuyên ngành Tin học
Thể loại Sáng kiến kinh nghiệm
Định dạng
Số trang 21
Dung lượng 3,84 MB

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

Nội dung

Chuyên đề bồi dưỡng học sinh giỏi: Cấu trúc dữ liệu heap và ứng dụng

Trang 1

MỤC LỤC

A Phần mở đầu 1

I Lý do chọn đề tài 1

II Mục đích của đề tài 1

III Nhiệm vụ và phương pháp nghiên cứu 1

VI Điểm mới trong kết quả nghiên cứu 1

MỤC LỤC 1

Khái niệm 3

Các thao tác thường dùng đối với Heap Max 3

Khai báo 3

UpHeap 4

DownHeap 4

Push 6

Pop 6

Dijkstra Heap 6

Một số bài tập ứng dụng 8

1.Bài tập 1: Thả xốp 8

2 Bài tập 2: PILOT 10

3 Bài tập 3: Tiểu thuyết trinh thám 13

4.Bài tập 4: BASE3 17

Tài liệu tham khảo 21

Trang 2

A PHẦN MỞ ĐẦU

I LÝ DO CHỌN ĐỀ TÀI

Công tác bồi dưỡng học sinh giỏi (HSG) là một công tác mũi nhọn trong việc nâng cao chất lượng giáo dục, tạo nguồn lực, bồi dưỡng nhân tài cho nhà trường nói riêng, cho địa phương nói chung Bồi dưỡng HSG là một công việc khó khăn và lâu dài, đòi hỏi nhiều công sức của thầy và trò.

Trong quá trình bồi dưỡng HSG môn Tin học ở bậc THPT thì cấu trúc dữ liệu heap

là cấu trúc dữ liệu đặc biệt quan trọng Từ lí do trên, tôi xin trình bày sáng kiến kinh nghiệm “CHUYÊN ĐỀ BỒI DƯỠNG HSG : CẤU TRÚC DỮ LIỆU HEAP VÀ ỨNG DỤNG”, để học sinh dễ dàng tiếp thu kiến thức mới.

Do lần đầu tiên thực hiện làm sáng kiến kinh nghiệm, nên không tránh khỏi những thiếu sót Mong quý thầy cô góp ý để lần sau làm tốt hơn.

II MỤC ĐÍCH CỦA ĐỀ TÀI

Heap là một trong những cấu trúc dữ liệu đặc biệt quan trọng, nó giúp ta có thể giải được nhiều bài toán trong thời gian cho phép Độ phức tạp thông thường khi làm việc với

Heap là O(logN) Khi được học chuyên đề này học sinh sẽ lập trình thành thạo với các bài

toán ứng dụng của heap.

III NHIỆM VỤ VÀ PHƯƠNG PHÁP NGHIÊN CỨU

Viết sáng kiến kinh nghiệm thường xuyên liên tục cũng là nhiệm vụ chính trị của mỗi giáo viên, nhưng cần phải lựa chọn phương pháp nghiên cứu đúng đắn và phù hợp với nhà trường trung học phổ thông Sáng kiến kinh nghiệm đang trình bày của tôi dựa theo các luận cứ khoa học hướng đối tượng, cụ thể: thuyết trình, quan sát, điều tra cơ bản, phân tích kết quả thực nghiệm sư phạm,v.v… phù hợp với bài học và môn học thuộc lĩnh vực cấu trúc dữ liệu.

IV ĐIỂM MỚI TRONG KẾT QUẢ NGHIÊN CỨU

Giúp học sinh hiểu rõ về cấu trúc dữ liệu heap và sử dụng thành thạo trong lập trình Ngoài ra, tôi mạnh dạn trình bày sáng kiến kinh nghiệm này còn để phục vụ cho những năm dạy tiếp theo

Trang 3

B PHẦN NỘI DUNG Cấu trúc dữ liệu HEAP

Khái niệm

Heap là một trong những cấu trúc dữ liệu đặc biệt quan trọng, nó giúp ta có thể giải được nhiều bài toán trong thời gian cho phép Độ phức tạp thông thường khi làm việc với

Heap là O(logN).

Heap thực chất là một cây cân bằng thỏa mãn các điều kiện sau:

• Một nút có không quá 2 nút con.

• Với Heap Max thì nút gốc là nút lớn nhất, mọi nút con đều không lớn hơn nút cha của nó Với Heap Min thì ngược lại

Mặc dù được mô tả như cây nhưng Heap có thể được biểu diễn bằng mảng Nút con của nút i là 2*i và 2*i+1 Do Heap là cây cân bằng nên độ cao của 1 nút luôn <= logN Ứng dụng chủ yếu của Heap là tìm Min, Max trong 1 tập hợp động (có thể thay đổi, thêm, bớt các phần tử) nhưng như vậy đã là quá đủ.

(Mô hình biểu diễn Heap bằng cây nhị phân và bằng mảng)

Các thao tác thường dùng đối với Heap Max

Khai báo

Ở ví dụ này, Heap sẽ là mảng một chiều kiểu LongInt, nHeap là số phần tử của mảng.

Trang 4

Nếu 1 nút lớn hơn nút cha của nó thì di chuyển nó lên trên:

Procedure UpHeap(i : LongInt);

Begin

if (i = 1) or (Heap[i] < Heap[i div 2]) then exit; // Nếu i là nút gốc hoặc

nhỏ hơn nút cha thì không làm việc

swap(Heap[i] , Heap[i div 2]); // Đổi chỗ 2 phần tử trong Heap;

UpHeap(i div 2); // Tiếp tục di chuyển lên trên

end;

DownHeap

Nếu 1 nút nhỏ hơn nút con thì đẩy nó xuống dưới:

Trang 5

Procedure DownHeap(i : LongInt);

Var

j : LongInt;

Begin

j := i*2;

if j > nHeap then exit; // Nếu i không có nút con thì không làm việc

if (j < nHeap) and (Heap[j] < Heap[j+1]) then Inc(j); // Nếu i có 2 nút con thì

chọn nút ưu tiên hơn

if Heap[i] < Heap[j] then // Nếu nút cha nhỏ hơn nút con

Trang 6

Inc(nHeap); // Tăng số phần tử của Heap

Heap[nHeap] := x; // Thêm x vào Heap

Pop := Heap[v]; // Lấy phần tử ở vị trí v ra khỏi Heap

Heap[v] := Heap[nHeap]; // Đưa phần tử ở cuối Heap vào vị trí v

Dec(nHeap); // Giảm số phần tử của Heap đi 1

{Chỉnh lại Heap}

UpHeap(v);

DownHeap(v);

End;

Ngoài ra, khi sử dụng thuật toán Dijkstra/Prim kết hợp cấu trúc Heap, bạn còn

có thể sử dụng cách Push và Pop khác thuận lợi hơn so với cách trình bày ở trên:

child := pos[v]; // child là vị trí của đỉnh v trong Heap

if child = 0 then // Nếu đỉnh v chưa có trong Heap

Trang 7

begin

Inc(nHeap); // Tăng số phần tử của Heap

child := nHeap; // Đưa v vào cuối Heap

end;

parent := child div 2; // parent là nút cha của child

while (parent > 0) and (d[Heap[parent]] > d[v]) do // Nếu đỉnh ở nút parent kém ưu tiên hơn v thì bị “kéo xuống” nút child

begin

Heap[child] := Heap[parent]; // Đẩy đỉnh được lưu trong nút cha xuống nút con pos[Heap[child]] := child; // Ghi nhận lại vị trí mới của đỉnh đó

child := parent; // Tiếp tục di chuyển lên

parent := child div 2;

v := Heap[nHeap]; // v là đỉnh ở nút lá cuối Heap, sẽ được đảo lên đầu và vun đống

Dec(nHeap); // Giảm số phần tử của Heap

pos[Heap[r]] := r; // Cập nhật lại vị trí mới trong Heap của đỉnh đó

r := c; // Tiếp tục di chuyển xuống dưới

end;

Heap[r] := v; // Đỉnh v được đặt vào vị trí r để đảm bảo cấu trúc Heap

pos[v] := r; // Ghi nhận vị trí mới của đỉnh v trong Heap

end;

Trang 8

Một số bài tập ứng dụng

1 Bài tập 1: Thả xốp

Có N hạt xốp, hạt thứ i có khối lượng , được thả lần lượt xuống một ống nước đặc biệt được thiết kế sao cho tại mỗi thời điểm chỉ có một hạt xốp nhẹ nhất nổi lên trên bề mặt Trước mỗi lần thả, hạt xốp đang nổi trên bề mặt sẽ bị ngấm nước và tăng gấp đôi khối lượng Hỏi sau khi thả hạt xốp cuối cùng vào ống thì khối lượng xốp tăng so với tổng khối lượng ban đầu là bao nhiêu ?

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

• Dòng 1: Số nguyên dương N

• Dòng 2: N số nguyên dương

Kết quả: Ghi ra file văn bản SPONGE.OUT

• Ghi 1 số duy nhất là đáp án của bài toán

Trang 9

If (heap[j] > heap[j+1]) and (j <nheap) then inc(j);

If heap[i] > heap[j] then

Trang 10

HT airline có tất cả N phi công (N là số chẵn), các phi công được đánh số từ 1 đến N (Phi công 1 là phi công trẻ nhất, phi công i là phi công có tuổi cao thứ i,… phi công n là

phi công cao tuổi nhất) HT airline cần chính xác

2

N

phi hành đoàn, mỗi phi hành đoàn

gồm 2 phi công (một lái chính và một lái phụ), lái chính phải nhiều tuổi hơn lái phụ.

Hợp đồng mà công ty kí với các phi công có 2 điều khoản rõ ràng: tiền lương khi là lái chính và tiền lương khi là lái phụ Rõ ràng, đối với 1 phi công, tiền lương lái chính bao giờ cũng cao hơn tiền lương khi lái phụ Tuy nhiên, với một phi hành đoàn, có thể tiền lương của lái chính lại thấp hơn lái phụ.

Để giảm chi phí trả tiền lương, HT phải xác định một cách phân chia tối ưu

2

N

phi hành đoàn.

Bạn hãy giúp HT viết chương trình xác định số tiền tối thiểu để trả lương cho N phi công.

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

• Dòng 1 : Số nguyên dương N, là số phi công ở HT airline.

• N dòng tiếp theo, dòng thứ i là thông tin về phi công i : gồm hai số a và c viết cách nhau 1 dấu cách trống, tương ứng là tiền lương khi lái chính và tiền lương khi lái phụ.

Kết quả: Dữ liệu ra ghi vào file PILOT.OUT

Một số nguyên duy nhất là tiền lương tối thiểu phải trả cho N phi công.

Hạn chế :

2 ≤ N ≤ 10000; N là số chẵn.

Trang 12

if (i = 1) or (h[i] < h[i div 2]) then exit;

if h[i div 2] < h[i] then

Trang 13

3 Bài tập 3: Tiểu thuyết trinh thám

Ivan Đneprôp viết truyện tiểu thuyết trinh thám Truyện của anh ta không có gì đặc sắc: không có các tình huống ly kỳ đặc biệt, cũng không có các chi tiết hài hước tế nhị Thậm chí một hiệu sách đã bán các sáng tác của Ivan theo cân! Nhưng độc giả lại thích truyện của Ivan Nó dễ hiểu và giúp người ta thư giản sau một ngày lao động mệt nhọc Thực ra, bí mật sự thành công của Ivan là ở chổ không phải chính anh nghĩ ra các tình huống mà là người em trai Alexei Ivan có nhiệm vụ viết nó thành các bestsellers Dĩ nhiên hai anh em chia nhau hợp lý số tiền kiếm được Điều đáng tiếc là khả năng sáng tạo các tình huống ly kỳ của Alexei lại phụ thuộc vào chu kỳ sinh học của anh Hai anh em phân tích bảng chu kỳ sinh học của Alexei và thấy rằng trong thời gian tới Alexei sẽ nghĩ

được n chủ đề mới, chủ đề thứ i sẽ được nghĩ ra ở ngày ri Trong cùng một ngày có thể Alexei nghĩ ra tới vài câu chuyện.

Với mỗi chủ đề, Ivan thời lượng cần thiết để hoàn thành tác phẩm và tính được rằng

chủ đề thứ i cần có pi ngày để viết Ivan có trí nhớ cực tốt, vì vậy anh có thể tạm bỏ dở một truyện, chuyển sang viết truyện khác sau đó quay lại hoàn thành nốt các truyện dở dang.

Dĩ nhiên, hai anh em muốn sách được viết càng nhanh càng tốt, tức là phải cực tiểu hóa thời gian trung bình từ thời điểm hiện tại tới thời điểm lúc tiểu thuyết hoàn thành Vì

số sách là cố định, nên điều này tương đương với việc cực tiểu hóa tổng thời gian viết tất

cả các cuốn sách Điều này có nghĩa là nếu cuốn sách thứ i được hoàn thành vào ngày ci

thì ∑ci phải được cực tiểu hóa Ví dụ, ở ngày thứ nhất Alexei nghĩ ra một cốt chuyện mà Ivan cần viết trong 5 ngày, Ivan bắt tay viết ngay Ngày thứ 2 Alexei nghĩ thêm một cót chuyện mới cần viết trong một ngày Ivan chuyển sang viết chuyện mới, ngày thứ 3:

Trang 14

chuện thứ hai hoàn thành và Ivan quay lại viết tiếp chuyện thứ nhất, mất thêm 4 ngày nữa, đến ngày thứ 7 chuyện thứ nhất hoàn thành Tổng các thời điểm hoàn thành là 3+7 = 10.

Yêu cầu: Cho n, ri và pi Hãy xác định tổng thời gian ngắn nhất hoàn thành tất cả các truyện.

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

Dòng 1: Chứa số nguyên n (1 ≤ n ≤ 100.000),

Mỗi dòng trong n dòng sau chứa 2 số nguyên ri và pi.

Kết quả: Ghi ra file PULP.OUT

• Một số nguyên – tổng thời gian ngắn nhất tìm được.

1 Sort tăng theo R[i]

2 Ví dụ với các thời điểm , dễ dàng ta thấy

3 Với mỗi khoảng thời gian t = R[i] – R[i-1], ta ưu tiên giải quyết công việc cần ít thời

gian nhất, giả sử là công việc P (Thấy ngay là sử dụng Heap để lấy công việc có thời gian nhỏ nhất)

a Nếu thời gian thực hiện công việc P < t thì thực hiện hết công việc P, thời gian còn lại thực hiện tiếp các công việc có thời gian nhỏ tiếp theo.

b Nếu thời gian thực hiện công việc P > t thì chúng ta thực hiện công việc P trong khoảng thời gian t, thời gian còn lại là t[P] – t ta lưu lại trong Heap để tính tiếp.

4 Sau khi xét đến thời điểm N, lúc này ta sẽ phải làm tất cả các công việc còn lại tuần

tự từ nhỏ đến lớn, hay là lấy tất cả các phần tử trong Heap ra là xong.

Trang 15

if (i = 1) or (h[i] > h[i div 2]) then exit;

if h[i div 2] > h[i] then

Trang 17

Cho 3 số ở hệ cơ số 3 (viết bởi 3 số 0, 1, 2) Hãy tìm một chữ số N ở hệ cơ số 3 sao cho N

có một số lẻ chữ số và số 1 nằm ở chính giữa số N Số N phải thu được từ việc liên kết 3

số cho trước, mỗi số trong 3 số có thể được sử dụng 0 hoặc nhiều lần:

020 2020

Trang 18

Ký tự 1 ở giữa của xâu kết quả phải thuộc 1 trong 3 xâu:

Giả sử ký tự 1 của kết quả nằm ở vị trí I của xâu , ta sẽ xây dựng xâu kết quả bằng cách thêm từng xâu vào trái hoặc phải (phần L là trái, ký tự 1 ở giữa, phần R là phải)

Ta sẽ xây dựng xâu đến khi thì dừng lại (yêu cầu đề bài)

Dễ thấy, ta chỉ quan tâm tới ghi nhận kết quả Tức là nếu tồn tại cách xây dựng L’, R’ mà

thỏa mãn cũng sử dụng cách xây dựng đó được với các cặp với , chỉ cần lưu 1 cặp có

Quy hoạch động = cách xếp có với

Nếu mỗi lần ta luôn nắp xâu vào nửa ngắn hơn thì luôn đảm bảo

thái + độ dài xâu nắp thêm vào Bài toán trở thành Dijkstra Heap

về trạng thái Các trạng thái cơ sở có thể là các ký tự 1 của 1 trong 3 xâu ban đầu Đáp án bài toán là

Trang 19

h[i] := h[i div 2] ;

h2[i] := h2[i div 2];

if d[x,y] <= d[h[j],h2[j]] then break ;

Trang 21

thể giải được nhiều bài toán trong thời gian cho phép Độ phức tạp thông thường khi làm

việc với Heap là O(lgN) Học sinh hiểu được bản chất của cấu trúc dữ liệu heap sẽ giúp

cho học sinh yêu thích môn học và ham học hỏi, tìm tòi, sáng tạo.

Đề tài này đã mang tính thực tiễn rất cao, cụ thể là: đây là kiến thức rất quan trọng trong quá trình bồi dưỡng học sinh giỏi.

Kết quả là có rất nhiều học sinh đã làm được các bài tập có ứng dụng của heap.

Tài liệu tham khảo

1 Giải thuật và lập trình – T.S Lê Minh Hoàng – ĐHSP Hà Nội

2 Website: www.infoarena.ro

XÁC NHẬN CỦA THỦ

TRƯỞNG ĐƠN VỊ

Thanh Hóa, ngày 19 tháng 5 năm 2013

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)

Nguyễn Đặng Phú

Ngày đăng: 30/05/2014, 14:48

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

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

w