Tài liệu chặt nhị phân cho bồi dưỡng HSG Tin Học

30 5.5K 9
Tài liệu chặt nhị phân cho bồi dưỡng HSG Tin Học

Đ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

I ĐẶT VẤN ĐỀ  Từ năm 2006 đến với việc đổi cách đề kỳ thi IOI kỳ thi học sinh giỏi môn Tin học có cách tiếp cận Những năm trước đề thi thường tập trung vào thuật toán phức tạp, nhiều học sinh phải thuộc lòng thuật toán áp dụng cách máy móc Hiện đề thi yêu cầu học sinh vận dụng thuật toán cách linh hoạt, với toán học sinh đưa thuật toán mà thuật toán phải “nhanh” đáp ứng yêu cầu thời gian Việc bồi dưỡng học sinh giỏi môn Tin học phần lớn tập trung mức độ tìm thuật toán cho toán Ví dụ: cho dãy số nguyên gồm N phần tử, xếp để dãy số cho trở thành dãy không giảm? Trước tiên ta có thuật toán xếp tráo đổi (thuật toán xếp“nổi bọt”) có độ phức tạp O(N2) Đây thuật toán khả thi trường hợp N ≤ 103, tăng số lượng phần tử lên khoảng 105 phần tử ta cần thuật toán xếp tốt như: QuickSort, MergeSort có độ phức tạp O(NlogN)  Từ vấn đề thực tiễn kỹ thuật “Chặt nhị phân” kỹ thuật giúp làm giảm thời gian thực thuật toán từ O(K) xuống O(logK) lý tác giả chọn đề tài   Trong trình giảng dạy thường chia kỹ thuật thành hai dạng:  Chặt nhị phân theo kết  Chặt nhị phân dãy số Nội dung đề tài thể hai kỹ thuật thông qua ví dụ cụ thể, với kỹ thuật trình bày theo cấu trúc:  Xét toán điển hình  Giải toán  Bài tập áp dụng II NỘI DUNG  CƠ SỞ LÝ LUẬN  Bản chất kỹ thuật “chặt nhị phân” thuật toán tìm kiếm nhị phân Thuật toán học sinh học chương trình lớp 10 THPT (trang 42 – SGK Tin học 10), chương trình Tin học lớp 11 lại lần đưa vào giảng dạy điều cho thấy tầm quan trọng thuật toán tìm kiếm nhị phân  Trước trình kỹ thuật “chặt nhị phân” ta tìm hiểu toán: Cho dãy A dãy tăng gồm N số nguyên khác a1, a2 ,an số nguyên K Hỏi dãy A có phần tử có giá trị K không?(SGK – Tin học 10) Để giải toán thuật toán tìm kiếm có độ phức tạp O(N), có thuật toán tìm kiếm nhị phân có độ phức tạp O(logN) với ý tưởng sau:  Vì dãy A dãy tăng nên ta tìm cách thu hẹp phạm vi tìm kiếm sau lần so sánh khóa với số hạng chọn Để làm điều đó, ta chọn số hạng Agiua “giữa dãy” để so sánh với k, Giua =[(N+1)/2] Khi xảy ba trường hợp:  Nếu Agiua = k giua là phần tử cần tìm, thông báo có phần tử K kết thúc thuật toán  Nếu Agiua >k việc tìm kiếm xét dãy a1,a2 ,agiua-1  Nếu Agiua =K); End;  Đoạn chương trình xét giá trị x sau: Res:=0;// Res biến lưu kết toán For x:=1 to (sum div k) If Check(x) then Res:=x; Ta thấy hàm Check(x) có độ phức tạp O(n), đoạn chương trình xét giá trị x có độ phức tạp O(nL) với L=min(sum div k, max(ai) ) Theo đề n ≤ 105 ≤ 109, giải thuật giải toán với liệu nhỏ Để giải trọn vẹn toán ta cần giảm độ phức tạp thuật toán Chi phí hàm Check(x) phụ thuộc vào N, ta giảm số phép thử x sau: Giả sử phạm vi giá trị [dau cuoi], xét giá trị x:=(dau+cuoi) div 2, Check(x) = true  kết toán x nằm đoạn [x+1 cuoi], ngược lại kết toán nằm đoạn [dau x-1], trình nàylặp lặp lại dau>=cuoi dừng Đoạn chương trình xét giá trị x viết lại sau: Res:=0; Dau:=0; cuoi:=sum div k+1; While ( dau A[CS[1]] then CS[1]:=i else if A[i] < A[CS[Res]] then Begin Inc(Res); CS[Res]:=i; End else Begin //Chặt nhị phân cập nhật lại mảng CS Dau:=1; Cuoi:=Res; While Dau y.b)); End; // Sắp xếp theo chiều giảm số đầu a Procedure QuickSort(l, r : longint); Var i, j : longint; x : doan; Begin If l >= r then exit; i := l; j := r; x := T[l + random(r - l + 1)]; Repeat While x < T[i] inc(i); While T[j] < x dec(j); If i j; QuickSort(l, j); QuickSort(i, r); End; Bước 2: Chặt nhị phân tìm độ dài dãy không giảm dài theo số B Procedure Solve; Var CS : array[1 maxn] of longint; res,dau,cuoi,giua, i : longint; Begin res := 1; CS[res] := 1; For i := to n If T[i].b < T[CS[1]].b then CS[1] := i Else If T[i].b >= T[CS[res]].b then Begin inc(res); CS[res] := i End Else Begin dau := 1; cuoi := res; While dau < cuoi Begin giua := (dau + cuoi) div 2; If T[i].b >= T[CS[giua]].b then dau := giua + else cuoi := giua; End; CS[dau] := i; End; writeln(res); End; Bài toán ta thuật toán khác cài đặt số nhị phân BIT để tìm độ dài dãy con, độ phức tạp thuật toán O(NlogN) Bài 2: SEQUENCES (Nguồn bài: UVA) W dãy số nguyên dương Nó có đặc điểm sau: - Độ dài dãy số lẻ: L = 2*N + - N + số nguyên dãy tạo thành dãy tăng - N + số nguyên cuối dãy tạo thành dãy giảm - Không có số nguyên cạnh dãy có giá trị Ví dụ: 1, 2, 3, 4, 5, 4, 3, 2, dãy W độ dài Tuy nhiên, dãy 1, 2, 3, 4, 5, 4, 3, 2, không dãy W Yêu cầu: Trong dãy dãy số cho trước, tìm dãy W có độ dài dài Dữ liệu Dòng 1: số nguyên dương N (N a[CS[Giua]] then Dau := Giua + else Cuoi := Giua; End; CS[Dau] := i; f1[i] := Dau; End; //Chặt nhị phân xây dựng mảng F2 d := 1; CS[d] := n; f2[n] := 1; For i := n - downto If a[i] < a[CS[1]] then Begin CS[1] := i; f2[i] := 1; End Else If a[i] > a[CS[d]] then Begin inc(d); CS[d] := i; f2[i] := d; End Else Begin Dau := 1; Cuoi := d; While Dau < Cuoi Begin Giua := (Dau + Cuoi) shr 1; If a[i] > a[CS[Giua]] then Dau := Giua + else Cuoi := Giua; End; CS[Dau] := i; f2[i] := Dau; End; End; Sau xây dựng xong mảng F1, F2 độ dài dãy W dài tính sau: For i := to n Begin If F1[i] < F2[i] then t := F1[i] else t := F2[i]; If Res < t then Res := t; End; writeln((res - 1) shl + 1); Bài 3: ROBOTCAM (Nguồn bài: Lê Minh Hoàng 2011) Cuộc thi RobotCam thi lớn robot tổ chức hàng năm hành tinh XYZ Sân chơi mô tả mặt phẳng với hệ toạ trực chuẩn Luật chơi mô tả sau: Trên mặt phẳng đặt n phần quà điểm hoàn toàn phân biệt Các đội tham gia thi phải dùng Robots để thu nhặt tất phần quà Vấn đề trở nên khó khăn đội chơi Robots tham gia thu nhặt quà không di chuyển cách tuỳ ý mà phải tuân thủ điều kiện sau: Đường robot phải bắt đầu kết thúc điểm số n điểm cho Trong trình di chuyển, robot không di chuyển tới điểm có hoành độ hay tung độ nhỏ hoành độ hay tung độ điểm đứng Hai đường hai robots khác điểm chung Đường gồm điểm chấp nhận hợp lệ Dưới hình mô tả vị trí điểm đánh dấu cách chơi hợp lệ: Yêu cầu: Hãy xác định số lượng robot cần sử dụng để thu nhặt tất phần quà Dữ liệu: Vào từ file văn ROBOTCAM.INP Dòng chứa số nguyên dương n ≤ 105 số lượng phần quà N dòng tiếp theo, dòng chứa hoành độ tung độ phần quà ghi cách dấu cách Các toạ độ số nguyên có giá trị tuyệt đối không 109 Kết quả: Ghi file văn ROBOTCAM.OUT số lượng Robots cần sử dụng Ví dụ: INPUT OUTPUT 1 2 Gợi ý: Khai báo mảng P gồm N phần tử phần tử gồm trường x y lưu tọa độ đặt phần quà Khai báo mảng H dùng để lưu tung độ Robots đặt Bước 1: Sắp xếp mảng P tăng theo tọa độ x, trường hợp ta xếp tăng theo tọa độ y Bước 2: Xét tọa độ (x,y) từ nhỏ tới lớn, với tọa độ chặt nhị phân xét xem Robots đươc đặt có Robot nhặt quà tọa độ xét không, ta thêm Robot vào nhặt quà tọa độ (x,y) Cài đặt: bước tương tự đoạn nguyên Bước ta cài đặt sau: Procedure Dem_so_Robots; Var Dau, Giua, Cuoi, i, tungdo: Integer; begin nRobots := 0; for i := to n begin tungdo := p[i].y; Dau:= 1;Cuoi:= nRobots; //h[1] > h[2] > > h[nRobots] while Dau < Cuoi //h[dau - 1] > tungdo >= h[cuoi+1] begin Giua:= (Dau+Cuoi) div 2; if h[Giua]>tungdo then Dau:= Giua+1 else Cuoi:= Giua; end; h[Dau] := tungdo; if Dau > nRobots then Inc(nRobots); end; end; //nRobots: số lượng rôbốt cần sử dụng (Nguồn bài: IOICAM 2006) Bài 4: CHIA DÃY Dãy số M phần tử B gọi dãy dãy số A gồm N phần tử tồn mã chuyển C gồm M phần tử thoả mãn B[i]=A[C[i]] với I = 1…M ≤ C[1] < C[2] < < C[m] ≤ N Một cách chia dãy A thành dãy "được chấp nhận" dãy dãy không giảm phần tử dãy A thuộc dãy Yêu cầu: Bạn chia dãy ban đầu thành dãy mà "được chấp nhận" Dữ liệu Dòng ghi số N số phần tử dãy A ( N ≤ 105 ) N dòng ghi N số tự nhiên phần tử dãy A ( Ai ≤ 109 ) Kết Ghi số lượng dãy thỏa mãn Ví dụ INPUT OUTPUT Gợi ý: Từ cách giải ROBOTCAM chứng minh cho nhận xét: Độ dài dãy giảm dài = Số lượng dãy không giảm mà phần tử dãy thuộc dãy Như toán đưa tìm độ dài dãy giảm dài dãy A Cách cài đặt chặt nhị phân tìm độ dài dãy tăng dài đổi chiều dấu so sánh Bài 5: SỐ LƯỢNG DÃY CON TĂNG Cho dãy số a1,a2, ,an Hãy đếm số lượng dãy tăng dài dãy số Một dãy độ dài k dãy a xác định số (u1≤u2≤u3≤ ≤uk) (1≤ui≤n) Hai dãy (u1,u2,u3, ,uk) (v1,v2,v3, ,vt) gọi khác k≠t tồn vị trí i cho ui≠vi Dữ liệu Dòng ghi số nguyên dương n (n≤105) Dòng ghi n số nguyên mô tả dãy a (ai≤109) Kết Một dòng ghi kết theo module 1000000007 Ví dụ INPUT 1 2 3 OUTPUT Gợi ý: Khai báo mảng A, phần tử ghi gồm trường: L, ID, Val Trong trường Val lưu giá trị dãy số, ID lưu số thứ tự ban đầu, L lưu độ dài dãy tăng dài kết thúc A[i].val Bài phải thực chặt nhị phân lần Lần 1: Chặt nhị phân để xây dựng giá trị cho trường L Res:=1; cs[1]:=1; a[1].l:=1; For i:=2 to n Begin If a[i].vala[cs[res]].val then Begin Inc(Res); cs[Res]:=i; a[i].l:=Res; End Else Begin Dau:=1; Cuoi:=Res; While Daua[cs[Giua]].val then Dau:=Giua+1 else Cuoi:=Giua; End; cs[Dau]:=i; a[i].l:=Dau; End; End; Sắp xếp dãy A theo trường L, L xếp theo vị trí mảng A ban đầu Sau xếp xong, với đoạn có L vị trí tăng dần hiển nhiên giá trị val giảm dần Gọi F[i] số lượng dãy tăng có độ dài lớn tính đến a[i] Với a[i] ta cần tìm a[j] có a[j].L=a[i].L-1 thỏa mãn a[j].val[...]... được yêu cầu Để xây dựng F1 và F2 ta thực hiện chặt nhị phân hai lần: Lần 1: tìm dãy con tăng bắt đầu từ đầu dãy để xây dựng F1 Lần 2: tìm dãy con tăng bắt đầu từ cuối dãy trở ngược về đầu dãy để xây dựng F2, về cơ bản hai đoạn chặt nhị phân này là giống nhau Procedure Solve; Var CS : array[1 maxn] of longint; i, d, Dau, Cuoi, Giua : longint; Begin / /Chặt nhị phân xây dựng mảng F1 d := 1; CS[d] := 1; f1[1]... thuật toán, nếu không kiểm soát được hai biến này chương trình có thể dẫn tới lặp vô hạn, đây là điều mà các học sinh rất ngại khi cài đặt bằng kỹ thuật trên Do đó luyện tập với nhiều bài tập vẫn là cách tốt nhất để rút ra cấu trúc chặt nhị phân cho riêng mình Hy vọng tài liệu sẽ giúp ích cho các học sinh, sinh vieen giỏi nhất là những em trong đội tuyển quốc gia, ACM bổ sung vào vốn kiến thức các em... d Việc này có thể làm được nếu ta sắp xếp thứ tự thời gian của mỗi người đến bến, và tìm kiếm nhị phân 1 lần nữa 2 Chặt nhị phân trên dãy số a Xét bài toán Cho một dãy gồm N số nguyên (1 ≤ N ≤ 106) Hãy tìm dãy con tăng dài nhất trong dãy đó In ra số lượng phần tử của dãy con Các số trong phạm vi longint Dữ liệu Dòng đầu tiên gồm số nguyên N Dòng thứ hai gồm N số mô tả dãy Kết quả Gồm một số nguyên... trường: L, ID, Val Trong đó trường Val lưu giá trị của dãy số, ID lưu số thứ tự ban đầu, L lưu độ dài của dãy con tăng dài nhất kết thúc tại A[i].val Bài này phải thực hiện chặt nhị phân 3 lần Lần 1: Chặt nhị phân để xây dựng giá trị cho trường L Res:=1; cs[1]:=1; a[1].l:=1; For i:=2 to n do Begin If a[i].vala[cs[res]].val then Begin Inc(Res);... a[j].val

Ngày đăng: 19/07/2016, 08:20

Từ khóa liên quan

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

Tài liệu liên quan