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

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

Đ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

MỤC LỤC A Phần mở đầu I Lý chọn đề tài II Mục đích đề tài III Nhiệm vụ phương pháp nghiên cứu VI Điểm kết nghiên cứu B Nội dung I Khái niệm II Các thao tác thường dùng Heap Max Khai báo 2 UpHeap 3 DownHeap Push 5 Pop Dijkstra Heap III Một số tập ứng dụng Bài tập 1: Thả xốp Bài tập 2: PILOT Bài tập 3: Tiểu thuyết trinh thám 12 Bài tập 4: BASE3 16 C Phần kết luận 20 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) công tác mũi nhọn 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 công việc khó khăn lâu dài, đòi hỏi nhiều công sức thầy trò Trong trình bồi dưỡng HSG môn Tin học bậc THPT cấu trúc liệu heap cấu trúc liệu đặc biệt quan trọng Từ lí trên, 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 Do lần thực làm sáng kiến kinh nghiệm, nên không tránh khỏi thiếu sót Mong quý thầy cô góp ý để lần sau làm tốt II MỤC ĐÍCH CỦA ĐỀ TÀI Heap cấu trúc liệu đặc biệt quan trọng, giúp ta giải nhiều toán thời gian cho phép Độ phức tạp thông thường làm việc với Heap O(logN) Khi học chuyên đề học sinh lập trình thành thạo với toán ứng dụng 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 nhiệm vụ trị giáo viên, cần phải lựa chọn phương pháp nghiên cứu đắn phù hợp với nhà trường trung học phổ thông Sáng kiến kinh nghiệm trình bày dựa theo luận khoa học hướng đối tượng, cụ thể: thuyết trình, quan sát, điều tra bản, phân tích kết thực nghiệm sư phạm,v.v… phù hợp với học môn học thuộc lĩnh vực cấu trúc liệu IV ĐIỂM MỚI TRONG KẾT QUẢ NGHIÊN CỨU Giúp học sinh hiểu rõ cấu trúc liệu heap sử dụng thành thạo lập trình Ngoài ra, mạnh dạn trình bày sáng kiến kinh nghiệm để phục vụ cho năm dạy B PHẦN NỘI DUNG Cấu trúc liệu HEAP I Khái niệm Heap cấu trúc liệu đặc biệt quan trọng, giúp ta giải nhiều toán thời gian cho phép Độ phức tạp thông thường làm việc với Heap O(logN) Heap thực chất cân thỏa mãn điều kiện sau:  Một nút có không nút  Với Heap Max nút gốc nút lớn nhất, nút không lớn nút cha Với Heap Min ngược lại Mặc dù mô tả Heap biểu diễn mảng Nút nút i 2*i 2*i+1 Do Heap cân nên độ cao nút nHeap then exit; // Nếu i nút không làm việc if (j < nHeap) and (Heap[j] < Heap[j+1]) then Inc(j); // Nếu i có nút chọn nút ưu tiên if Heap[i] < Heap[j] then // Nếu nút cha nhỏ nút begin swap(Heap[i] , Heap[j]); // Đổi chỗ phần tử Heap DownHeap(j); // Tiếp tục di chuyển xuống end; end; 4 Push Đưa phần tử vào Heap: Thêm nút vào cuối Heap tiến hành UpHeap từ đây: Procedure Push(x : LongInt); Begin Inc(nHeap); // Tăng số phần tử Heap Heap[nHeap] := x; // Thêm x vào Heap UpHeap(nHeap); End; Pop Rút phần tử vị trí v Heap: Gán Heap[v] := Heap[nHeap] tiến hành chỉnh lại Heap: Function Pop(v : LongInt) : LongInt; Begin Pop := Heap[v]; // Lấy phần tử vị trí v 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ử Heap {Chỉnh lại Heap} UpHeap(v); DownHeap(v); End; Ngoài ra, sử dụng thuật toán Dijkstra/Prim kết hợp cấu trúc Heap, bạn sử dụng cách Push Pop khác thuận lợi so với cách trình bày trên: Dijkstra Heap 1/ Update – Dijkstra: Procedure Update(v : LongInt); // Đỉnh v vừa sửa nhãn, cần chỉnh lại Heap var child , parent : LongInt; begin child := pos[v]; // child vị trí đỉnh v Heap if child = then // Nếu đỉnh v chưa có Heap begin Inc(nHeap); // Tăng số phần tử Heap child := nHeap; // Đưa v vào cuối Heap end; parent := child div 2; // parent nút cha child while (parent > 0) and (d[Heap[parent]] > d[v]) // Nếu đỉnh nút parent ưu tiên v bị “kéo xuống” nút child begin Heap[child] := Heap[parent]; // Đẩy đỉnh lưu nút cha xuống nút pos[Heap[child]] := child; // Ghi nhận lại vị trí đỉnh child := parent; // Tiếp tục di chuyển lên parent := child div 2; end; Heap[child] := v; // Thao tác “kéo xuống” tạo ô trống nút child để đặt v vào pos[v] := child; // Ghi nhận vị trí đỉnh v Heap end; 2/ Pop – Dijkstra: Function Pop : LongInt; // Lấy từ Heap đỉnh có nhãn tự nhỏ var r , v , c : LongInt; begin Pop := Heap[1]; // Nút gốc nút có nhãn tự nhỏ v := Heap[nHeap]; // v đỉnh nút cuối Heap, đảo lên đầu vun đống Dec(nHeap); // Giảm số phần tử Heap r := 1; // Bắt đầu từ nút gốc while r*2 d[Heap[c+1]]) then Inc(c); // Trong nút chọn nút chứa đỉnh ưu tiên if d[Heap[c]] >= d[v] then break; // Nếu v ưu tiên không làm việc Heap[r] := Heap[c]; // Chuyển đỉnh lưu nút lên nút cha pos[Heap[r]] := r; // Cập nhật lại vị trí Heap đỉnh r := c; // Tiếp tục di chuyển xuống end; Heap[r] := v; // Đỉnh v đặt vào vị trí r để đảm bảo cấu trúc Heap pos[v] := r; // Ghi nhận vị trí đỉnh v Heap end; III Một số tập ứng dụng Bài tập 1: Thả xốp Có N hạt xốp, hạt thứ i có khối lượng , thả xuống ống nước đặc biệt thiết kế cho thời điểm có hạt xốp nhẹ lên bề mặt Trước lần thả, hạt xốp bề mặt bị ngấm nước tăng gấp đôi khối lượng Hỏi sau thả hạt xốp cuối vào ống khối lượng xốp tăng so với tổng khối lượng ban đầu ? Dữ liệu: Vào từ file vă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 file văn SPONGE.OUT  Ghi số đáp án toán Ví dụ: SPONGE.INP SPONGE.OUT 3 Thuật toán : Dễ thấy danh sách động (giá trị phần tử thay đổi), ta xây dựng heapmin để lấy hạt xốp nhỏ nhất, tăng gấp đôi khối lượng cập nhật lại heapmin Const tfi='sponge.inp'; tfo='sponge.out'; Type arr1=array[0 100001] of longint; Var fi,fo : text; w,heap,head,ke,d,c,dd,cost : n,nheap,delta : longint; arr1; {==================================} Procedure nhap; Var i : longint; Begin Assign(fi,tfi);Reset(fi); read(fi,n); For i := to n read(fi,w[i]); cost := w; Close(fi); End; {==================================} Procedure doicho(var x,y : longint); var tmp : longint; Begin tmp := x; x := y; y := tmp; End; {==================================} Procedure upheap(i : longint); Var j : longint; Begin While (i 1) and (heap[i] < heap[i div 2]) Begin doicho(heap[i],heap[i div 2]); i := i div 2; End; End; {=============================} Procedure downheap(i : longint); Var j : longint; Begin While (2*i heap[j+1]) and (j heap[j] then Begin doicho(heap[i],heap[j]); i :=j; End else exit; End; End; {=============================} Procedure push(x : longint); Begin inc(nheap); heap[nheap] := x; upheap(nheap); End; {=============================} Procedure xuly; Var i1 : longint; Begin For i1 := to n-1 Begin push(w[i1]); delta := delta + heap[1]; heap[1] := heap[1]*2; downheap(1); End; End; BEGIN Assign(fo,tfo);Rewrite(fo); nhap; xuly; write(fo,delta); Close(fo); END Bài tập 2: PILOT HT AIRLINE hãng hàng không danh tiếng Việt Nam, nhiên, để tồn bão suy thoái kinh tế, Ban giám đốc định giảm chi phi tiền lương cho phi công nhiều tốt HT airline có tất N phi công (N số chẵn), phi công đánh số từ đến N (Phi công phi công trẻ nhất, phi công i phi công có tuổi cao thứ i,… phi công n phi công cao tuổi nhất) HT airline cần xác N phi hành đoàn, phi hành đoàn gồm phi công (một lái lái phụ), lái phải nhiều tuổi lái phụ Hợp đồng mà công ty kí với phi công có điều khoản rõ ràng: tiền lương lái tiền lương lái phụ Rõ ràng, phi công, tiền lương lái cao tiền lương lái phụ Tuy nhiên, với phi hành đoàn, tiền lương lái lại thấp lái phụ Để giảm chi phí trả tiền lương, HT phải xác định cách phân chia tối ưu N phi hành đoàn Bạn 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 PILOT.INP  Dòng : Số nguyên dương N, số phi công HT airline  N dòng tiếp theo, dòng thứ i thông tin phi công i : gồm hai số a c viết cách dấu cách trống, tương ứng tiền lương lái tiền lương lái phụ Kết quả: Dữ liệu ghi vào file PILOT.OUT Một số nguyên tiền lương tối thiểu phải trả cho N phi công Hạn chế :  N  10000; N số chẵn  a < c  100.000 Ví dụ : PILOT.INP PILOT.OUT PILOT.INP PILOT.OUT 32000 33000 10000 7000 5000 3000 9000 3000 4000 1000 6000 4000 9000 7000 5000 1000 11000 5000 9000 3000 7000 3000 8000 6000 8000 6000 Time limits / test: 1s Thuật toán: Ta có nhận xét sau: Theo thứ tự i nhập vào từ đến N, i lẻ phải có lái phụ Vì vậy, ta xây dựng heap max, cho vào heap, i lẻ ta lấy heap nút, lái phụ CONST tfi tfo max = = = 'pilot.inp'; 'pilot.out'; 100000; TYPE Arr1 = array[1 max] of longint; VAR fi,fo : text; n,nh,sum,kq : longint; a,b,h : Arr1; {* -*} procedure nhap; var i : longint; begin assign(fi,tfi);reset(fi); read(fi,n); For i := to n read(fi,a[i],b[i]); close(fi); end; {* -*} procedure doicho(var x,y : longint); var tg : longint; begin tg := x; x := y; y := tg; 10 end; {* -*} procedure upheap(i : longint); begin if (i = 1) or (h[i] < h[i div 2]) then exit; if h[i div 2] < h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* -*} procedure downheap(i : longint); var j : longint; begin j := *i; if j > nh then exit; if (j < nh) and (h[j] < h[j+1]) then inc(j); if h[i] < h[j] then begin doicho(h[i],h[j]); downheap(j); end; end; {* -*} procedure push(x : longint); begin inc(nh); h[nh] := x; upheap(nh); end; {* -*} function pop : longint; begin pop := h[1]; h[1] := h[nh]; dec(nh); downheap(1); end; {* -*} procedure xuli; var i : longint; begin sum := 0;nh := 0;kq := 0; For i := to n begin sum := sum + a[i]; push(a[i] - b[i]); if i mod = then kq := kq + pop; end; end; {* -*} procedure inkq; begin 11 assign(fo,tfo);rewrite(fo); write(fo,sum-kq); close(fo); end; {* -*} BEGIN nhap; xuli; inkq; END 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 sắc: tình ly kỳ đặc biệt, chi tiết hài hước tế nhị Thậm chí hiệu sách bán sáng tác Ivan theo cân! Nhưng độc giả lại thích truyện Ivan Nó dễ hiểu giúp người ta thư giản sau ngày lao động mệt nhọc Thực ra, bí mật thành công Ivan chổ anh nghĩ tình mà người em trai Alexei Ivan có nhiệm vụ viết thành bestsellers Dĩ nhiên hai anh em chia hợp lý số tiền kiếm Điều đáng tiếc khả sáng tạo tình ly kỳ Alexei lại phụ thuộc vào chu kỳ sinh học anh Hai anh em phân tích bảng chu kỳ sinh học Alexei thấy thời gian tới Alexei nghĩ n chủ đề mới, chủ đề thứ i nghĩ ngày ri Trong ngày Alexei nghĩ tới vài câu chuyện Với chủ đề, Ivan thời lượng cần thiết để hoàn thành tác phẩm tính chủ đề thứ i cần có pi ngày để viết Ivan có trí nhớ cực tốt, anh tạm bỏ dở truyện, chuyển sang viết truyện khác sau quay lại hoàn thành nốt truyện dở dang Dĩ nhiên, hai anh em muốn sách viết nhanh tốt, tức phải cực tiểu hóa thời gian trung bình từ thời điểm tới thời điểm lúc tiểu thuyết hoàn thành Vì số sách cố định, nên điều tương đương với việc cực tiểu hóa tổng thời gian viết tất sách Điều có nghĩa sách thứ i hoàn thành vào ngày ci c i phải cực tiểu hóa Ví dụ, ngày thứ Alexei nghĩ cốt chuyện mà Ivan cần viết ngày, Ivan bắt tay viết Ngày thứ Alexei nghĩ thêm cót chuyện cần viết ngày Ivan chuyển sang viết chuyện mới, ngày thứ 3: chuện thứ hai hoàn thành Ivan quay lại viết tiếp chuyện thứ nhất, thêm ngày nữa, đến ngày thứ chuyện thứ hoàn thành Tổng thời điểm hoàn thành 3+7 = 10 12 Yêu cầu: Cho n, ri pi Hãy xác định tổng thời gian ngắn hoàn thành tất truyện Dữ liệu: Vào từ file văn PULP.INP:  Dòng 1: Chứa số nguyên n (1 ≤ n ≤ 100.000),  Mỗi dòng n dòng sau chứa số nguyên ri pi Kết quả: Ghi file PULP.OUT  Một số nguyên – tổng thời gian ngắn tìm Ví dụ: PULP.INP PULP.OUT 10 Thuật toán: Sort tăng theo R[i] Ví dụ với thời điểm , dễ dàng ta thấy Với khoảng thời gian t = R[i] – R[i-1], ta ưu tiên giải công việc cần thời gian nhất, giả sử công việc P (Thấy 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 công việc P < t thực hết công việc P, thời gian lại thực tiếp công việc có thời gian nhỏ b Nếu thời gian thực công việc P > t thực công việc P khoảng thời gian t, thời gian lại t[P] – t ta lưu lại Heap để tính tiếp Sau xét đến thời điểm N, lúc ta phải làm tất công việc lại từ nhỏ đến lớn, lấy tất phần tử Heap xong CONST tfi tfo max = = = 'pulp.inp'; 'pulp.out'; 100000; TYPE Arr1 = array[1 max] of longint; VAR fi,fo : n,nh,sum,res : r,p,h : text; longint; Arr1; 13 {* *} procedure nhap; var i : longint; begin assign(fi,tfi);reset(fi); read(fi,n); For i := to n read(fi,r[i],p[i]); close(fi); end; {* *} procedure doicho(var x,y : longint); var tg : longint; begin tg := x; x := y; y := tg; end; {* *} procedure upheap(i : longint); begin if (i = 1) or (h[i] > h[i div 2]) then exit; if h[i div 2] > h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* *} procedure downheap(i : longint); var j : longint; begin j := * i; if j > nh then exit; if (j < nh) and (h[j] > h[j+1]) then inc(j); if h[i] > h[j] then begin doicho(h[i],h[j]); downheap(j); end; end; {* *} procedure push(x : longint); begin inc(nh); h[nh] := x; upheap(nh); end; {* *} function pop : longint; begin pop := h[1]; h[1] := h[nh]; dec(nh); downheap(1); 14 end; {* *} procedure xuli; var i,t,x : longint; begin nh := 0; push(p[1]); sum := r[1]; res := 0; For i := to n begin t := r[i] - r[i-1]; while (nh > 0) and (t > 0) begin x := pop; if (x begin x := pop; sum := sum + x; res := res + sum; end; end; {* *} procedure sort(x,y:longint); var i,j,key1,key2 : longint; begin i := x; j := y; key1 := r[x+random(y-x+1)]; key2 := p[x+random(y-x+1)]; repeat while (r[i] < key1) or ((r[i] = key1) and (p[i] < key2)) inc(i); while (r[j] > key1) or ((r[j] = key1) and (p[j] > key2)) dec(j); if i j ; if x < j then sort(x,j); if y > i then sort(i,y); end; {* *} procedure inkq; begin assign(fo,tfo);rewrite(fo); write(fo,res); close(fo); end; {* *} BEGIN randomize; nhap; sort(1,n); xuli; inkq; END Bài tập 4: BASE3 Cho số hệ số (viết số 0, 1, 2) Hãy tìm chữ số N hệ số cho N có số lẻ chữ số số nằm số N Số N phải thu từ việc liên kết số cho trước, số số sử dụng nhiều lần: Yêu cầu: Xác định số lượng nhỏ chữ số N thỏa mãn tính chất đầu Dữ liệu: BASE3.INP Gồm dòng, dòng số hệ số Kết quả: BASE3.OUT Số lượng chữ số nhỏ N Nếu không tồn N ghi số Hạn chế  Số chữ số số số đầu cho khoảng từ đến 16.000 Ví dụ: BASE3.INP BASE3.OUT 001 13 020 2020 Giải thích N = 2020001001001 16 Time limit/test: 0.4 L R Ký tự xâu kết phải thuộc xâu: Giả sử ký tự kết nằm vị trí I xâu , ta xây dựng xâu kết cách thêm xâu vào trái phải (phần L trái, ký tự giữa, phần R phải) Ta xây dựng xâu đến dừng lại (yêu cầu đề bài) Dễ thấy, ta quan tâm tới ghi nhận kết Tức tồn cách xây dựng L’, R’ mà thỏa mãn sử dụng cách xây dựng với cặp với , cần lưu cặp có Quy hoạch động = cách xếp có Nếu lần ta nắp xâu vào nửa ngắn đảm bảo ) Với trạng thái (do , ta cập nhật cho trạng + độ dài xâu nắp thêm vào Bài toán trở thành Dijkstra Heap thái trạng thái với Các trạng thái sở ký tự xâu ban đầu Đáp án toán {$H+} uses math ; const tfi = tfo = Nmax = vc = type arr1 = var fi,fo : n,m,nh,ss,xi,yi s : len : d : pos : h,h2 : procedure Nhap; var i,j :longint; begin ss := 0; 'Base3.inp'; 'Base3.out'; 16001; 1000000000000000000 ; array[0 Nmax] of longint ; text; : longint; array[1 3] of string ; array[1 3] of longint ; array[-Nmax Nmax,0 1] of int64 ; array[-Nmax Nmax,0 1] of longint; array[0 4*Nmax] of longint; 17 for i := to begin readln(fi,s[i]); len[i] := length(s[i]); ss := max(ss,len[i]) ; end; end; procedure Upheap(i:longint) ; var x,y:longint ; begin x := h[i] ; y := h2[i]; while (i > 1) and (d[x,y] < d[h[i div 2],h2[i div 2]]) begin h[i] := h[i div 2] ; h2[i] := h2[i div 2]; pos[h[i],h2[i]] := i ; i := i div 2; end ; h[i] := x; h2[i] := y; pos[x,y] := i; end; procedure downheap(i:longint); var j,x,y:longint; begin x := h[i]; y := h2[i]; while i * d[h[j+1],h2[j+1]]) then inc(j); if d[x,y] = -ss) and (d[j,yi] > d[xi,yi] + len[i]) then begin d[j,yi] := d[xi,yi] + len[i]; push(j,yi) ; end ; end; end ; procedure init; var i,j,k,u: longint; begin for i := -ss to ss for j := to d[i,j] := vc ; for i := to for j := to len[i] if s[i][j] = '1' then begin if s[i][1] = '0' then k := else k := 1; u := (j - 1) - (len[i] - j) ; d[u,k] := len[i] ; push(u,k) ; end; end; procedure xuly; var i,j,k: longint; begin while nh > begin pop; if (xi = 0) then begin write(fo,d[xi,yi]); exit; end; update; 19 end; write(fo,0) ; end ; begin assign(fi,tfi);reset(fi); assign(fo,tfo);rewrite(fo); Nhap; init; xuly; close(fi); close(fo) ; end C PHẦN KẾT LUẬN Cấu trúc liệu heap đóng vai trò quan trọng lập trình, giúp ta giải nhiều toán thời gian cho phép Độ phức tạp thông thường làm việc với Heap O(lgN) Học sinh hiểu chất cấu trúc liệu heap giúp cho học sinh yêu thích môn học ham học hỏi, tìm tòi, sáng tạo Đề tài mang tính thực tiễn cao, cụ thể là: kiến thức quan trọng trình bồi dưỡng học sinh giỏi Kết có nhiều học sinh làm tập có ứng dụng heap Tài liệu tham khảo Giải thuật lập trình – T.S Lê Minh Hoàng – ĐHSP Hà Nội Website: www.infoarena.ro XÁC NHẬN CỦA THỦ TRƯỞNG ĐƠN VỊ Thanh Hóa, ngày 19 tháng năm 2013 Tôi xin cam đoan SKKN viết, không chép nội dung người khác (Ký ghi rõ họ tên) Nguyễn Đặng Phú 20 [...]... close(fi); close(fo) ; end C PHẦN KẾT LUẬN Cấu trúc dữ liệu heap đóng vai trò hết sức quan trọng trong lập trình, 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(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,... 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... 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... 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 12 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 Ví dụ: PULP.INP... 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... 5000 1000 11000 5000 9000 3000 7000 3000 8000 6000 8000 6000 Time limits / test: 1s Thuật toán: Ta có nhận xét sau: Theo thứ tự i nhập vào từ 1 đến N, thì cứ i lẻ thì phải có 1 lái phụ Vì vậy, ta xây dựng một heap max, lần lượt cho vào heap, khi i lẻ thì ta lấy trong heap ra một nút, đây chính là lái phụ CONST tfi tfo max = = = 'pilot.inp'; 'pilot.out'; 100000; TYPE Arr1 = array[1 max] of longint; VAR... 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: Yêu cầu: Xác định số lượng nhỏ nhất các chữ số của N thỏa mãn tính chất đầu bài Dữ liệu: BASE3.INP Gồm 3 dòng, mỗi dòng là một số ở hệ cơ số 3 Kết quả: BASE3.OUT Số lượng chữ... 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ó Nếu mỗi lần ta luôn nắp xâu vào nửa ngắn hơn thì luôn... -*} procedure upheap(i : longint); begin if (i = 1) or (h[i] < h[i div 2]) then exit; if h[i div 2] < h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* -*} procedure downheap(i : longint); var j : longint; begin j := 2 *i; if j > nh then exit; if (j < nh) and (h[j] < h[j+1]) then inc(j); if h[i] < h[j] then begin doicho(h[i],h[j]); downheap(j); end;... *} procedure upheap(i : longint); begin if (i = 1) or (h[i] > h[i div 2]) then exit; if h[i div 2] > h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* *} procedure downheap(i : longint); var j : longint; begin j := 2 * i; if j > nh then exit; if (j < nh) and (h[j] > h[j+1]) then inc(j); if h[i] > h[j] then begin doicho(h[i],h[j]); downheap(j); end; end;

Ngày đăng: 05/06/2016, 23:01

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan