1. Trang chủ
  2. » Luận Văn - Báo Cáo

Tài liệu giáo khoa chuyên tin, q 1

219 6 0
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 đề 1 Thuật Toán Và Phân Tích Thuật Toán
Trường học Trường chuyên
Chuyên ngành Tin học
Thể loại Tài liệu giáo khoa
Năm xuất bản 2009
Thành phố Hà Nội
Định dạng
Số trang 219
Dung lượng 2,08 MB

Nội dung

Hồ sĩ đàm (Chủ biên) đỗ đức đông lê minh hoàng nguyễn hùng tài liệu giáo khoa chuyên tin Nhà xuất giáo dục việt nam CuuDuongThanCong.com Tai ngay!!! Ban co the xoa dong chu nay!!! https://fb.com/tailieudientucntt Công ty Cổ phần dịch vụ xuất Giáo dục Hà Nội - Nhà xuất Giáo dục Việt Nam giữ quyền công bố tác phẩm 349-2009/CXB/43-644/GD M4 sè : 8I746H9 CuuDuongThanCong.com https://fb.com/tailieudientucntt LỜI NÓI ðẦU Bộ Giáo dục ðào tạo ban hành chương trình chuyên tin học cho lớp chuyên 10, 11, 12 Dựa theo chun đề chun sâu chương trình nói trên, tác giả biên soạn sách chuyên tin học, bao gồm vấn ñề cấu trúc liệu, thuật tốn cài đặt chương trình Bộ sách gồm ba quyển, 1, Cấu trúc bao gồm: phần lí thuyết, giới thiệu khái niệm bản, cần thiết trực tiếp, thường dùng nhất; phần áp dụng, trình bày tốn thường gặp, cách giải cài đặt chương trình; cuối tập Các chuyên ñề sách ñược lựa chọn mang tính hệ thống từ ñến chuyên sâu Với trải nghiệm nhiều năm tham gia giảng dạy, bồi dưỡng học sinh chuyên tin học trường chuyên có truyền thống uy tín, tác giả lựa chọn, biên soạn nội dung bản, thiết yếu mà sử dụng để dạy học với mong muốn sách phục vụ không cho giáo viên học sinh chuyên PTTH mà cho giáo viên, học sinh chuyên tin học THCS làm tài liệu tham khảo cho việc dạy học Với kinh nghiệm nhiều năm tham gia bồi dưỡng học sinh, sinh viên tham gia kì thi học sinh giỏi Quốc gia, Quốc tế Hội thi Tin học trẻ Toàn quốc, Olympiad Sinh viên Tin học Tồn quốc, Kì thi lập trình viên Quốc tế khu vực ðông Nam Á, tác giả ñã lựa chọn giới thiệu tập, lời giải có định hướng phục vụ cho khơng học sinh mà sinh viên làm tài liệu tham khảo tham gia kì thi Lần đầu tập sách biên soạn, thời gian trình độ có hạn chế nên chắn cịn nhiều thiếu sót, tác giả mong nhận ý kiến đóng góp bạn ñọc, ñồng nghiệp, sinh viên học sinh ñể sách ñược ngày hoàn thiện Các tác giả CuuDuongThanCong.com https://fb.com/tailieudientucntt CuuDuongThanCong.com https://fb.com/tailieudientucntt Chuyên đề THUẬT TỐN VÀ PHÂN TÍCH THUẬT TỐN Thuật toán Thuật toán khái niệm quan trọng tin học Thuật ngữ thuật toán xuất phát từ nhà khoa học Arập Abu Ja'far Mohammed ibn Musa al Khowarizmi Ta hiểu thuật tốn dãy hữu hạn bước, bước mô tả xác phép tốn hành động cần thực hiện, ñể giải vấn ñề ðể hiểu ñầy ñủ ý nghĩa khái niệm thuật toán xem xét đặc trưng sau thuật tốn: • ðầu vào (Input): Thuật toán nhận liệu vào từ tập • ðầu (Output): Với tập liệu đầu vào, thuật tốn đưa liệu tương ứng với lời giải tốn • Chính xác: Các bước thuật tốn mơ tả xác • Hữu hạn: Thuật tốn cần phải ñưa ñược ñầu sau số hữu hạn (có thể lớn) bước với đầu vào • ðơn trị: Các kết trung gian bước thực thuật tốn xác định cách đơn trị phụ thuộc vào ñầu vào kết bước trước • Tổng quát: Thuật tốn áp dụng để giải tốn có dạng cho ðể biểu diễn thuật tốn biểu diễn danh sách bước, bước ñược diễn ñạt ngôn ngữ thông thường kí hiệu tốn học; biểu diễn thuật tốn sơ đồ khối Tuy nhiên, để đảm bảo tính xác định thuật tốn, thuật tốn cần viết ngơn ngữ lập trình Một chương trình biểu diễn thuật tốn ngơn ngữ lập trình chọn Trong tài liệu này, sử dụng ngơn ngữ tựa Pascal để trình bày thuật tốn Nói tựa Pascal, nhiều trường hợp, ngắn gọn, khơng hồn tồn tn CuuDuongThanCong.com https://fb.com/tailieudientucntt theo quy định Pascal Ngơn ngữ Pascal ngơn ngữ đơn giản, khoa học, giảng dạy nhà trường phổ thơng Ví dụ: Thuật tốn kiểm tra tính ngun tố số nguyên dương    2, viết ngôn ngữ lập trình Pascal function is_prime(n):boolean; begin for k:=2 to n-1 if (n mod k=0) then exit(false); exit(true); end; Phân tích thuật tốn 2.1 Tính hiệu thuật toán Khi giải toán, cần chọn số thuật toán thuật toán mà cho “tốt” Vậy dựa sở để đánh giá thuật tốn “tốt” thuật tốn kia? Thơng thường ta dựa hai tiểu chuẩn sau: Thuật tốn đơn giản, dễ hiểu, dễ cài đặt (dễ viết chương trình) Thuật tốn hiệu quả: Chúng ta thường ñặc biệt quan tâm ñến thời gian thực thuật tốn (gọi độ phức tạp tính tốn), bên cạnh quan tâm tới dung lượng khơng gian nhớ cần thiết để lưu giữ liệu vào, kết trung gian q trình tính tốn Khi viết chương trình để sử dụng số lần tiêu chuẩn (1) quan trọng, viết chương trình để sử dụng nhiều lần, cho nhiều người sử dụng tiêu chuẩn (2) lại quan trọng Trong trường hợp này, dù thuật tốn phải cài ñặt phức tạp, ta lựa chọn ñể nhận chương trình chạy nhanh hơn, hiệu 2.2 Tại cần thuật tốn có tính hiệu quả? Kĩ thuật máy tính tiến nhanh, ngày máy tính lớn đạt tốc độ tính tốn hàng nghìn tỉ phép tính giây Vậy có cần phải tìm thuật tốn hiệu hay khơng? Chúng ta xem lại ví dụ tốn kiểm tra tính nguyên tố số nguyên dương    2 function is_prime(n):boolean; begin CuuDuongThanCong.com https://fb.com/tailieudientucntt for k:=2 to n-1 if (n mod k=0) then exit(false); exit(true); end; Dễ dàng nhận thấy rằng,  số nguyên tố phải   phép tốn  Giả sử siêu máy tính tính trăm nghìn tỉ 10   phép  giây, ñể kiểm tra số khoảng 25 chữ số khoảng    ~3170 năm Trong đó, ta có nhận xét việc thử  từ ñến   không cần thiết mà cần thử  từ ñến √ , ta có: function is_prime(n):boolean; begin for k:=2 to trunc(sqrt(n)) if (n mod k=0) then exit(false); exit(true); end; {hàm sqrt(n) hàm tính √, trunc(x) hàm làm trịn x } Như để kiểm tra số khoảng 25 chữ số khoảng   !"  # ~0.03 giây! 2.3 ðánh giá thời gian thực thuật tốn Có hai cách tiếp cận để đánh giá thời gian thực thuật toán Cách thứ thực nghiệm, viết chương trình cho chạy chương trình với liệu vào khác máy tính Cách thứ hai phương pháp lí thuyết, coi thời gian thực thuật toán hàm số cỡ liệu vào (cỡ liệu vào tham số ñặc trưng cho liệu vào, có ảnh hưởng định đến thời gian thực chương trình Ví dụ tốn kiểm tra số ngun tố cỡ liệu vào số  cần kiểm tra; hay với toán xếp dãy số, cỡ liệu vào số phần tử dãy) Thông thường cỡ liệu vào số nguyên dương , ta sử dụng hàm số %  cỡ liệu vào để biểu diễn thời thực thuật toán Xét ví dụ tốn kiểm tra tính ngun tố số nguyên dương  (cỡ liệu vào ),  số chẵn  & 2 cần lần thử chia để kết luận  số nguyên tố Nếu   & 3 không chia hết cho lại chia hết cho cần lần thử (chia chia 3) để kết luận  khơng ngun tố Cịn  số ngun tố thuật toán phải thực nhiều lần thử CuuDuongThanCong.com https://fb.com/tailieudientucntt Trong tài liệu này, hiểu hàm số % thời gian nhiều cần thiết ñể thực thuật tốn với liệu đầu vào cỡ  Sử dụng kí hiệu tốn học lớn để mơ tả độ lớn hàm % Giả sử  số nguyên dương, % ' hai hàm thực không âm Ta viết % ( )' tồn số dương *  , cho % + *  ', với    Nếu thuật tốn có thời gian thực % ( )' nói thuật tốn có thời gian thực cấp ' Ví dụ: Giả sử % (  , 2, ta có  , 2 +  , 2 ( 3 với   Vậy % ( ) , trường hợp ta nói thuật tốn có thời gian thực cấp  2.4 Các quy tắc ñánh giá thời gian thực thuật tốn ðể đánh giá thời gian thực thuật tốn trình bày ngơn ngữ tựa Pascal, ta cần biết cách ñánh giá thời gian thực câu lệnh Pascal Trước tiên, xem xét câu lệnh Pascal Các câu lệnh Pascal ñược ñịnh nghĩa ñệ quy sau: Các phép gán, ñọc, viết câu lệnh (ñược gọi lệnh ñơn) Nếu S1, S2, , Sm câu lệnh Begin S1; S2; …; Sm; End; câu lệnh (ñược gọi lệnh hợp thành hay khối lệnh) Nếu S1 S2 câu lệnh E biểu thức lơgic If E then S1 else S2; câu lệnh (ñược gọi lệnh rẽ nhánh hay lệnh If) Nếu S câu lệnh E biểu thức lơgic While E S; câu lệnh (ñược gọi lệnh lặp ñiều kiện trước hay lệnh While) Nếu S1, S2,…,Sm câu lệnh E biểu thức lôgic Repeat S1; S2; …; Sm; Until E; câu lệnh (ñược gọi lệnh lặp ñiều kiện sau hay lệnh Repeat) CuuDuongThanCong.com https://fb.com/tailieudientucntt Nếu S lệnh, E1 E2 biểu thức kiểu thứ tự đếm For i:=E1 to E2 S; câu lệnh (ñược gọi lệnh lặp với số lần xác ñịnh hay lệnh For) ðể ñánh giá, phân tích chương trình xuất phát từ lệnh ñơn, ñánh giá lệnh phức tạp hơn, cuối ñánh giá ñược thời gian thực chương trình, cụ thể: Thời gian thực lệnh ñơn: gán, ñọc, viết )1 Lệnh hợp thành: giả sử thời gian thực S1, S2,…,Sm tương ứng )' , )' , , )'  Khi thời gian thực lệnh hợp thành là: )/0' , ' , … , '  Lệnh If: giả sử thời gian thực S1, S2 tương ứng )' , )'  Khi thời gian thực lệnh If là: )/0' , '  Lệnh lặp While: giả sử thời gian thực lệnh S (thân lệnh While) )' 2 số lần lặp tối ña thực lệnh S Khi ñó thời gian thực lệnh While )'2 Lệnh lặp Repeat: giả sử thời gian thực khối lệnh Begin S1; S2;…; Sm; End; )' 2 số lần lặp tối đa Khi thời gian thực lệnh Repeat )'2 Lệnh lặp For: giả sử thời gian thực lệnh S )' 2 số lần lặp tối đa Khi thời gian thực lệnh For )'2 2.5 Một số ví dụ Ví dụ 1: Phân tích thời gian thực chương trình sau: var i, j, n :longint; s1, s2 :longint; BEGIN {1} readln(n); {2} s1:=0; {3} for i:=1 to n {4} s1:=s1 + i; {5} s2:=0; CuuDuongThanCong.com https://fb.com/tailieudientucntt {6} {7} {8} {9} END for j:=1 to n s2:=s2 + j*j; writeln('1+2+ +',n,'=',s1); writeln('1^2+2^2+ +',n,'^2=',s2); Thời gian thực chương trình phụ thuộc vào số Các lệnh {1}, {2}, {4}, {5}, {7}, {8}, {9} có thời gian thực )1 Lệnh lặp For {3} có số lần lặp , lệnh {3} có thời gian thực ) Tương tự lệnh lặp For {6} có thời gian thực ) Vậy thời gian thực chương trình là: max)1, )1, ), )1, ), )1, )1 ( ) Ví dụ 2: Phân tích thời gian thực đoạn chương trình sau: {1} {2} {3} {4} {5} {6} c:=0; for i:=1 to 2*n c:=c+1; for i:=1 to n for j:=1 to n c:=c+1; Thời gian thực chương trình phụ thuộc vào số  Các lệnh {1}, {3}, {6} có thời gian thực )1 Lệnh lặp For {2} có số lần lặp 2, lệnh {2} có thời gian thực ) Lệnh lặp For {5} có số lần lặp , lệnh {5} có thời gian thực ) Lệnh lặp For {4} có số lần lặp , lệnh {4} có thời gian thực )  Vậy thời gian thực ñoạn chương trình là: max)1, ), )  ( )  Ví dụ 3: Phân tích thời gian thực ñoạn chương trình sau: {1} {2} {3} for i:=1 to n for j:=1 to i c:=c+1; Thời gian thực chương trình phụ thuộc vào số  Các lệnh {3} có thời gian thực )1 10 CuuDuongThanCong.com https://fb.com/tailieudientucntt : Thứ tự duyệt ñến duyệt xong • • Khi bắt đầu vào thủ tục ta nói ñỉnh  ñược duyệt ñến hay ñược thăm (discover), có nghĩa thời điểm đó, q trình tìm kiếm theo chiều sâu bắt ñầu từ  xây dựng nhánh DFS gốc  Khi chuẩn bị thoát khỏi thủ tục để lùi , ta nói đỉnh  ñược duyệt xong (finish), có nghĩa thời ñiểm đó, q trình tìm kiếm theo chiều sâu từ  kết thúc Trong mơ hình duyệt DFS trên, sử dụng biến ñếm zI ñể xác ñịnh thời ñiểm duyệt ñến lk thời ñiểm duyệt xong :k ñỉnh  Thứ tự 149 CuuDuongThanCong.com https://fb.com/tailieudientucntt duyệt đến duyệt xong có ý nghĩa quan trọng nhiều thuật tốn có áp dụng DFS, chẳng hạn thuật tốn tìm thành phần liên thơng mạnh, thuật tốn xếp tơ pơ… ðịnh lí 5-6 Với hai đỉnh phân biệt , : • ðỉnh  ñược duyệt ñến thời gian từ lk ñến :k : lmn  mlk , :k n  hậu duệ  DFS • ðỉnh  duyệt xong thời gian từ lk ñến :k : :mn  mlk , :k n  hậu duệ  DFS Chng minh Bản chất việc ñỉnh  ñược duyệt ñến (hay duyệt xong) thời gian từ lk đến :k thủ tục ˆy‰   gọi (hay thốt) mà thủ tục ˆy‰   ñã bắt ñầu chưa kết thúc, nghĩa thủ tục ˆy‰   ñược dây chuyền ñệ quy từ ˆy‰   gọi tới ðiều  nằm nhánh DFS gốc , hay nói cách khác,  hậu duệ  Hệ Với hai ñỉnh phân biệt ,  hai ñoạn mlk , :k n ml" , :" n rời chứa Hai ñoạn mlk , :k n ml" , :" n chứa   có quan hệ tiền bối–hậu duệ Chng minh Dễ thấy hai ñoạn mlk , :k n ml" , :" n khơng rời lk  ml" , :" n l"  mlk , :k n, tức hai ñỉnh ,  có quan hệ tiền bối–hậu duệ, áp dụng ðịnh lí 5-6, ta có ðPCM Với hai đỉnh phân biệt    mà ,     phải ñược duyệt ñến trước  ñược duyệt xong: ðịnh lí 5-7 Chng minh ,    ‘ l" ’ :k (0.1) ðây tính chất quan trọng thuật tốn DFS Hãy để ý thủ tục ˆy‰  , trước (duyệt xong ), qt tất ñỉnh chưa thăm nối từ  gọi đệ quy để thăm đỉnh đó, tức  phải ñược duyệt ñến trước  ñược duyệt xong: l" ’ :k ðỉnh  hậu duệ thực ñỉnh  DFS thời điểm lk mà thuật tốn thăm tới ñỉnh , tồn ñường ñi từ  ðịnh lí 5-8 (định lí đường trắng) 150 CuuDuongThanCong.com https://fb.com/tailieudientucntt tới  mà ngoại trừ ñỉnh , tất ñỉnh khác ñường ñi ñều chưa ñược thăm Chng minh “⇒” Nếu  hậu duệ , ta xét ñường ñi từ  tới  dọc cung DFS Tất ñỉnh } nằm sau  ñường ñi ñều hậu duệ , nên theo ðịnh lí 5-6, ta có lk ’ l“ , tức vào thời điểm lk , tất đỉnh } chưa ñược thăm “⇐” Nếu thời ñiểm lk , tồn ñường ñi từ  tới  mà ngoại trừ ñỉnh , tất ñỉnh khác ñường ñi ñều chưa ñược thăm, ta chứng minh ñỉnh ñường ñi ñều hậu duệ  Thật vậy, giả sử phản chứng  ” ñỉnh ñầu tiên ñường ñi mà hậu duệ , tức tồn ñỉnh } liền trước  ” ñường ñi hậu duệ  Theo ðịnh lí 5-7,  ” phải ñược thăm trước duyệt xong }: l" ” ’ :“ ; } lại hậu duệ  nên theo ðịnh lí 5-6, ta có :“ :k , l" ” ’ :k Mặt khác theo giả thiết thời điểm lk  ” chưa ñược thăm, tức lk ’ l" ” , kết hợp lại ta có l"”  mlk , :k n,  ” hậu duệ  theo ðịnh lí 5-6, trái với giả thiết phản chứng Tên gọi “định lí đường trắng: white-path theorem” xuất phát từ cách trình bày thuật tốn DFS chế tơ màu đồ thị: Ban đầu đỉnh tơ màu trắng, duyệt đến đỉnh đỉnh tơ màu xám duyệt xong đỉnh đỉnh tơ màu đen: ðịnh lí phát biểu: ðiều kiện cần ñủ ñể ñỉnh  hậu duệ thực ñỉnh  DFS thời điểm đỉnh  tơ màu xám, tồn ñường ñi từ  tới  mà ngoại trừ ñỉnh , tất ñỉnh khác ñường ñi có màu trắng 3.4 Thuật tốn tìm kiếm theo chiều rộng a) Ý tưởng Tư tưởng thuật toán tìm kiếm theo chiều rộng (Breadth-First Search – BFS) “lập lịch” duyệt ñỉnh Việc thăm ñỉnh lên lịch duyệt đỉnh nối từ cho thứ tự duyệt ưu tiên chiều rộng (ñỉnh gần ñỉnh xuất phát ñược duyệt trước) ðầu tiên ta thăm ñỉnh Việc thăm ñỉnh phát sinh thứ tự thăm ñỉnh + , 5 , … nối từ (những ñỉnh gần nhất) Tiếp theo ta thăm ñỉnh + , thăm ñỉnh + lại phát sinh yêu cầu thăm ñỉnh + , 5 , … nối từ + Nhưng rõ ràng ñỉnh  “xa” ñỉnh  nên chúng ñược thăm tất ñỉnh  ñã thăm Tức thứ tự duyệt ñỉnh là: , + , 5 , … , + , 5 , … 151 CuuDuongThanCong.com https://fb.com/tailieudientucntt + + 5 5 …… …… Thăm trước tất ñỉnh  Thăm sau tất đỉnh  Hình 5-12: Thứ tự thăm đỉnh BFS Thuật tốn tìm kiếm theo chiều rộng sử dụng danh sách ñể chứa ñỉnh ñang “chờ” thăm Tại bước, ta thăm ñỉnh ñầu danh sách, loại khỏi danh sách cho đỉnh chưa “xếp hàng” kề với xếp hàng thêm vào cuối danh sách Thuật toán kết thúc danh sách rỗng Vì nguyên tắc vào trước trước, danh sách chứa ñỉnh ñang chờ thăm ñược tổ chức dạng hàng đợi (Queue): Nếu ta có •  hàng ñợi với thủ tục (  ñể ñẩy ñỉnh  vào hàng ñợi hàm ( trả ñỉnh lấy từ hàng ñợi mơ hình giải thuật BFS viết sau: Queue := (s); //Khởi tạo hàng ñợi gồm ñỉnh s for ∀vV avail[v] := True; avail[s] := False; //ðánh dấu có đỉnh s xếp hàng repeat //Lặp tới hàng ñợi rỗng u := Pop; //Lấy từ hàng ñợi ñỉnh u Output ← u; //Liệt kê u for ∀vV:avail[v] and (u, v)E //Xét ñỉnh v kề u chưa ñược ñẩy vào hàng ñợi begin trace[v] := u; //Lưu vết ñường ñi Push(v); //ðẩy v vào hàng ñợi avail[v] := False; //ðánh dấu v ñã xếp hàng end; until Queue = t; if avail[t] then //s ñi tới ñược t «Truy theo vết từ t để tìm đường từ s tới t»; 152 CuuDuongThanCong.com https://fb.com/tailieudientucntt b) Cài ñặt  BFS.PAS  Tìm đường BFS {$MODE OBJFPC} program Breadth_First_Search; const maxN = 100000; maxM = 1000000; var adj: array[1 maxM] of Integer; //Các danh sách kề head: array[0 maxN] of Integer; //Mảng đánh dấu vị trí cắt đoạn adj avail: array[1 maxN] of Boolean; trace: array[1 maxN] of Integer; n, s, t: Integer; Queue: array[1 maxN] of Integer; front, rear: Integer; procedure Enter; //Nhập liệu var u, v, i: Integer; begin ReadLn(n, s, t); i := 0; for u := to n begin //Đọc danh sách kề u repeat read(v); if v then //Thêm v vào mảng adj begin Inc(i); adj[i] := v; end; until v = 0; head[u] := i; //Đọc hết dịng, đánh dấu vị trí cắt đoạn thứ u ReadLn; end; head[0] := 0; //Cầm canh end; procedure BFS; //Thuật tốn tìm kiếm theo chiều rộng var u, i: Integer; begin front := 1; rear := 1; //front: số ñầu hàng ñợi; rear: số cuối hàng ñợi Queue[1] := s; //Khởi tạo hàng ñợi ban ñầu có đỉnh s 153 CuuDuongThanCong.com https://fb.com/tailieudientucntt FillChar(avail[1], n * SizeOf(avail[1]), True); //Các đỉnh ñều chưa xếp hàng avail[s] := False; //ngoại trừ ñỉnh s ñã xếp hàng repeat u := Queue[front]; Inc(front); //Lấy từ hàng ñợi ñỉnh u Write(u, ', '); //Liệt kê u for i := head[u - 1] + to head[u] //Duyệt ñỉnh adj[i] nối từ u if avail[adj[i]] then //Nếu đỉnh chưa thăm begin Inc(rear); Queue[rear] := adj[i]; //Đẩy vào hàng ñợi avail[adj[i]] := False; trace[adj[i]] := u; //Lưu vết ñường ñi end; until front > rear; end; procedure PrintPath; //In đường ñi từ s tới t begin if avail[t] then //Từ s khơng có đường tới t WriteLn(' There is no path from ', s, ' to ', t) else begin WriteLn('The path from ', s, ' to ', t, ':'); while t s //Truy vết ngược từ t s begin Write(t, '

Ngày đăng: 02/11/2023, 12:19

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

TÀI LIỆU LIÊN QUAN