Tập X được chia ra thành các tập con Ai Ai , họ các tập con Ai này đượcgọi là 1 phân hoạch hay chia lớp của tập X khi nó giao nhau từng đôi một bằngrỗng và hợp lại bằng tập lớn X.. Kh
Trang 1Tài liệu
BỒI DƯỠNG HỌC SINH GIỎI
MÔN TIN HỌC (THCS)
(Tài liệu lưu hành nội bộ)
Người biên soạn : Lê Đắc Ước
ĐT : 0907090779 – E-mail : ledacuoc@yahoo.com
Trang 2(Lưu ý : Thường khi viết số ở hệ đếm thập phân người ta không ghi cơ số)
2 Hệ đếm nhị phân (Binary) : Gồm 2 chữ số biểu diễn (0,1)
a) Dạng tổng quát : a1a2…an = a1.2n-1 + a2.2n-2 + … + an.20
VD : 10102 = 1.23 + 0.22 + 1.21 + 0.20 = 10
(Lưu ý : Đây chính là cách quy đổi từ hệ nhị phân sang hệ thập phân)
b) Cách quy đổi từ thập phân sang nhị phân :
- B ư ớc 1 : Chia liên tiếp số cần đổi cho 2 đến khi thương bằng 0.
- B ư ớc 2 : Viết ngược lại số dư, ta được số mới trong hệ nhị phân.
VD : Đổi số 6 từ hệ thập phân sang hệ nhị phân, ta làm như sau :
(Lưu ý : Đây chính là cách quy đổi từ hệ Hexa sang hệ thập phân)
b) Cách quy đổi từ TP sang Hexa :
- B ư ớc 1 : Chia liên tiếp số cần đổi cho 16 đến khi thương bằng 0.
- B ư ớc 2 : Viết ngược lại số dư, ta được số mới trong hệ Hexa.
(Lưu ý : Nếu số dư lớn hơn 9 ta quy đổi thành A, B, C, D, E, F)
Giáo dục có rễ đắng mà trái
ngọt
Aristote (384-322 T.C.N)
Ngừng chia
Trang 3Haxa ra nhóm 4 số nhị phân (nếu chưa đủ 4 chữ số nhị phân ta phải thêm các chữ
số 0 vào phía trước) Ngược lại, muốn đổi từ hệ nhị phân sang Hexa, ta nhóm từphải sang trái, mỗi nhóm 4 số rồi quy đổi từng nhóm sang hệ Hexa
4 Phép nhân (Multiplication) : A B = {(a,b) | a A và b B}
5 Phép phân hoạch (Partition) :
Cho X là một tập hợp (X )
Tập X được chia ra thành các tập con Ai (Ai ), họ các tập con Ai này đượcgọi là 1 phân hoạch (hay chia lớp) của tập X khi nó giao nhau từng đôi một bằngrỗng và hợp lại bằng tập lớn X Tức là : A B = , i j và
i Ai = X
6 Hiệu đối xứng (Symmetric difference) : A B = (A \ B) (B \ A)
III SỐ NGUYÊN TỐ :
- Khái niệm : Số nguyên tố là số tự nhiên lớn hơn 1, chỉ có 2 ước là 1 và chính nó.
- Định lí : Mọi hợp số n đều có ít nhất một ước nguyên tố không vuợt quá n
IV ƯỚC SỐ CHUNG LỚN NHẤT - BỘI SỐ CHUNG NHỎ NHẤT :
- Thuật toán Euclid : Để tìm ƯCLN(a,b), ta có thể làm bằng cách trừ liên tiếp
số lớn cho số nhỏ tới khi 2 số bằng nhau (hoặc chia liên tiếp tới khi số dư bằng0), giá trị cuối cùng của a hoặc b chính là ƯCLN(a,b)
- Bổ đề : ƯCLN(a,0) = |a|, a ≠ 0
- UCLN(a,b)·BCNN(a, b)=a·bBCNN(a,b)=UCLN(a,a.b b)UCLN(a,b)=
b) BCNN(a,
Nếu a ≠ 0 thì phương trình có nghiệm là x = - a b
2 Phương trình bậc hai : ax 2 + bx + c = 0 (a ≠ 0) Ta tính = b2 – 4ac
Nếu < 0 thì phương trình vô nghiệm
Nếu = 0 thì phương trình có 1 nghiệm x = - 2b a
Nếu > 0 thì phương trình có 2 nghiệm phân biệt : x1=
2
b a
;x2 =
2
b a
3 Bất phương trình bậc nhất : ax + b > 0 (2)
Nếu a = 0 thì (2) b > 0 Khi đó : b ≤ 0 thì bất PT vô nghiệm;
Trang 4b > 0 thì bất PT có vô số nghiệm.Nếu a > 0 thì bất phương trình có nghiệm là x > - a b
Nếu a < 0 thì bất phương trình có nghiệm là x < - a b
'x b y c a
c y b x a
Nếu D = 0 thì : + Nếu Dx ≠ 0 hoặc Dy ≠ 0 thì hệ PT vô nghiệm;
+ Nếu Dx = Dy = 0 thì hệ PT có vô số nghiệm
Nếu D ≠ 0 thì hệ PT có nghiệm duy nhất : x D D x
và yD D y
VI SỐ GẦN ĐÚNG – SAI SỐ :
- Sai số là hiệu số giữa trị số đúng và trị số gần đúng
- Nếu a là số gần đúng của số đúng thì được gọi là sai sốtuyệt đối của số gần đúng a
- Nếu thì hay , ta nói a là số gầnđúng của với độ chính xác d, và qui ước viết gọn là
VII GIẢI TÍCH TỔ HỢP :
1 Hoán vị :
- Cho tập hợp A có n phần tử (n >0) Khi sắp xếp n phần tử này theo một thứ
tự, ta được 1 hoán vị các phần tử của tập A
- Số các hoán vị của một tập hợp có n phần tử là : Pn = 1.2.3… (n-1).n
2 Chỉnh hợp :
- Cho tập hợp A gồm n phần tử Mỗi cách sắp k phần tử của tập hợp A (1kn) theo một thứ tự nhất định gọi là một chỉnh hợp chập k của n phần tử củatập A
- Số các chỉnh hợp chập k của một tập hợp có n phần tử ( ) là:
3 Tổ hợp :
- Cho tập hợp A gồm n phần tử Mỗi cách sắp k phần tử của tập hợp A (1
kn) (không quan tâm thứ tự) gọi là một tổ hợp chập k của n phần tử của tập A.
- Số các tổ hợp chập k của một tập hợp có n phần tử ( ) là:
VIII HÌNH HỌC :
1 Đ ịnh lí Py-ta-go : ABC vuông tại A BC2 = AB2 + AC2
2 Hệ thức lượng trong vuông : b2=ab’(c2=ac’); h2=b’c’; 2 2 2
1 1 1
h b c
Trang 5Chương II : MỘT SỐ VẤN ĐỀ CƠ BẢN TRONG PASCAL
I GIẢI THUẬT :
1 Khái niệm :
- Giải thuật (còn gọi là thuật toán) là một tập hữu hạn các thao tác (các côngviệc, các phép toán…) có thể đặt tên được và chúng được thực hiện theo mộttrình tự thích hợp đối với một số đối tượng nào đó để đạt được điều mong muốn
2 Biểu diễn giải thuật :
Thông thường, người ta sử dụng một trong 4 cách sau để biểu diễn giải thuật :
- Liệt kê : Là hình thức liệt kê từng bước bằng ngôn ngữ tự nhiên
- Lưu đồ : Là hình thức biểu diễn giải thuật dưới dạng sơ đồ
- Dùng ngôn ngữ lập trình
- Dùng ngôn ngữ mã giả
II CÁC PHÉP TOÁN CƠ BẢN - LỆNH GÁN :
1 Các phép tính : + ; - ; * ; / (chia cho thương là số thực); DIV (chia lấy phần
nguyên); MOD (Chia lấy phần dư)
2 Các phép so sánh : > ; < ; = ; <> ; >= ; <=
3 Các phép Logic : AND (và); OR (hoặc); XOR (hoặc triệt tiêu); NOT (phủ định)
True True True True False FalseTrue False False True True FalseFalse True False True True TrueFalse False False False False True
4 Phép gán (Lệnh gán) : V := E; {V là 1 biến, E là biểu thức VD : X := -b/a; }
III CÁC KHAI BÁO : (Thường theo thứ tự như sau)
1 Khai báo tên chương trình : PROGRAM <Tên chương trình>;
2 Khai báo sử dụng đơn vị chương trình : USES <DS đơn vị chương trình>;
3 Khai báo nhãn : LABEL <Tên nhãn>;
4 Khai báo hằng : CONST <tên hằng> = <Giá trị>; VD : Const Pi=3.14;
5 Khai báo kiểu dữ liệu mới : TYPE <Tên kiểu DL mới>=Định nghĩa kiểu;
6 Khai báo biến : VAR <DS biến 1> : <Kiểu DL 1>; <DS biến 2> : <Kiểu DL 2>;
7 Khai báo thủ tục (một dạng chương trình con) :
PROCEDURE <Tên thủ tục> (Các tham số nếu cần);
8 Khai báo hàm (một dạng chương trình con) :
FUNCTION <Tên hàm> (Các tham số nếu cần) : <Kiểu DL của hàm>;
Trang 6IV CÁC KIỂU DỮ LIỆU ĐƠN GIẢN :
Integer, Real, Char, String, Boolean, String, String [k], đoạn con, liệt kê
Mở rộng ki u s nguyên : ểu số nguyên : ố nguyên :
Từ khai báo Phạm vi biểu diễn Chữ số có nghĩa Kích thước (Byte)
REAL 2.9E-39 1.7E+38 11-12 6
SINGLE 1.5E- 45 3.4E+38 7-8 4
DOUBLE 5.0E-324 1.7E+308 15-16 8
EXTENDED 3.4E- 4951 1.1E+4932 19-20 10
(Thông thường chỉ dùng kiểu Real Muốn sử dụng các kiểu thực
khác thì phải dùng hướng dẫn dịch {N+} ở đầu chương trình)
V CÁC THỦ TỤC CƠ BẢN CỦA TP :
1 Thủ tục nhập : READ
- Read (DS biến); hoặc Readln (DS biến); {Nhập vào biến giá trị từ bàn phím}
- Read (F, DS biến); hoặc Readln (F, DS biến); {Đọc từ tệp F vào DS biến}
- Readln; {Chờ nhấn phím Enter}
Thủ tục nhập đặc biệt: Readkey; {Cho kí tự khi gõ phím mà không cần nhấn Enter}
Hàm KeyPressed cho giá trị True nếu bàn phím có kí tự gõ, ngược lại có giá trị False.
2 Thủ tục xuất : WRITE
- Write (DS dữ liệu xuất); hoặc Writeln (DS dữ liệu xuất); {Xuất ra màn hình}
- Write (n:d); hoặc Writeln (n:d); {Dành d vị trí để xuất biến nguyên}
- Write (x:d:d1); hoặc Writeln (x:d:d1);
{Dành d vị trí để xuất biến thực với d1 kí số thập phân}
- Write (F, DSDL xuất); hoặc Writeln (F, DSDL xuất);{Ghi dữ liệu vào tệp F}
- Write (LST, DSDL xuất); hoặc Writeln (LST, DSDL xuất);{Xuất ra máy in}
- Writeln; {Xuống dòng}
- Write(#7); hoặc Write(Chr(7)); {Phát ra một tiếng chuông ở loa của máy}
3 Các thủ tục điều khiển màn hình :
ClrScr; {Xóa mành hình}
ClrEol; {Xóa từ vị trí con trỏ tới cuốn dòng}
DelLine; {Xóa toàn bộ dòng chứa con trỏ, sau đó dồn các dòng dưới lên}
InsLine; {Xen một dòng trắng vào màn hình từ vị trí con trỏ}
Gotoxy (Cột, dòng); {Chuyển tới tọa độ cột, dòng}
Hàm WhreX cho giá trị cột hiện thời Hàm WhreY cho giá trị dòng hiện thời.
Textbackground (color) hoặc Textbackground (0 tới 15); {định màu nền} TextColor (color) hoặc TextColor (số từ 0 tới 15); {định màu chữ}
Trang 7Halt; {Ngừng chương trình}
VI MỘT SỐ CẤU TRÚC ĐIỀU KHIỂN :
1 Câu lệnh điều kiện IF :
Dạng 1 : IF <Điều kiện> THEN <Câu lệnh>;
Dạng 2 : IF <Điều kiện> THEN <Câu lệnh 1> ELSE <Câu lệnh 2>;
(Lưu ý : Trước ELSE của lệnh IF không được viết dấu chấm phẩy)
2 Câu lệnh lựa chọn CASE :
CASE <Biểu thức> OF CASE <Biểu thức> OF
<Giá trị 1> : <Câu lệnh 1>; <Giá trị 1> : <Câu lệnh 1>;
<Giá trị 2> : <Câu lệnh 2>; <Giá trị 2> : <Câu lệnh 2>;
<Giá trị n> : <Câu lệnh n>; <Giá trị n> : <Câu lệnh n>;
END;
(Lưu ý : CASE kết thúc bằng END; Trước ELSE của CASE được chấm phẩy )
3 Điều khiển lặp FOR…TO/ FOR…DOWNTO :
Dạng 1 : FOR <Biến đếm> := <Trị đầu> TO <Trị cuối> DO <Câu lệnh>;
Dạng 2 : FOR <Biến đếm> := <Trị đầu> DOWNTO <Trị cuối> DO <Câu lệnh>;
4 Điều khiển lặp REPEAT…UNTIL : Ngừng lặp khi <Điều kiện> ĐÚNG REPEAT
UNTIL <Điều kiện>;
5 Điều khiển lặp WHILE…DO : Ngừng lặp khi <Điều kiện> SAI.
WHILE Điều kiện DO Câu lệnh;
(Sau DO chỉ có 1 câu lệnh, do đó muốn lặp nhiều phát biểu ta phải dùng phát biểu ghép)
6 Lệnh ghép : Ở những chỗ ta chỉ được sử dụng 1 câu lệnh, nhưng ta lại muốn
sử dụng nhiều hơn 1 câu lệnh thì phải sử dụng lệnh ghép Lệnh ghép có dạng :
Trang 8VII CÁCH ĐẶT TÊN TRONG PASCAL - TỪ KHÓA:
1 Cách đặt tên trong Pascal (chương trình, biến, hằng, nhãn, thủ tục, hàm… ) :
Tên có thể được đặt bằng một dãy bao gồm chữ cái, chữ số, dấu “_” (gạchnối dưới) nhưng bắt đầu của tên bắt buộc phải là một chữ cái Tên không được cókhoảng trắng và tên không được trùng với từ khóa
2 Từ khóa trong Pascal (Phải học thuộc lòng) :
And, Array, Begin, Case, Const, Div, Do, Downto, Else, End, File, For, Function, Goto, If, In, Label, Mod, Nil, Not, Of, Or, Packed, Procedure, Program, Record, Repeat, Set, String, Then, To, Type, Until, Uses, Var, While, With.
ORD (ch) : Cho thứ tự của kí tự ch trong bảng ASCII (VD : ORD (‘A’)=65, ORD (‘a’)=97).
CHR (i) : Cho kí tự có thứ tự là i trong bảng ASCII (VD : CHR (65) = ‘A’).
ODD (n) : Cho giá trị True nếu n là số lẻ.
SOUND(F) : tạo âm thanh tần số F tính theo Hz cho đến khi gặp lệnh OSOUND.NOSOUND; : Ngừng thực hiện hàm SOUND
DELAY (T) : tạo thời gian trể T tính theo đơn vị Mili giây (T là số nguyên).READKEY; : Nhận một kí tự từ bàn phím không đưa ra màn hình và không cần
gõ phím Enter (VD : Ch := Readkey;)WHEREX : Cho giá trị cột hiện thời của con trỏ
WHEREY : Cho giá trị dòng hiện thời của con trỏ
LENGTH (Chuỗi) : Cho độ dài thật của chuỗi
<Chuỗi>[k] : cho kí tự thứ k trong chuỗi Đặc biệt : Chuỗi [0]=Length(chuỗi)
VD : For i:=1 to length(st) do
If ord(st[i]) >= 97 then st[i] := chr(ord(st)-32);
{Duyệt chuỗi st để đổi chuỗi st bất kỳ thành chuỗi gồm toàn chữ in hoa}LENGTH (S,P,N) : xóa trong chuỗi S đi N ký tự kể từ vị trí P
POS (S1,S) : Tìm kiếm chuỗi S1 trong chuỗi S (Hàm cho giá trị là vị trí đầu tiên)
Trang 9Chương III : CHƯƠNG TRÌNH CON : THỦ TỤC VÀ HÀM
I THỦ TỤC (PROCEDURE) VÀ HÀM (FUNCTION) :
1 Xét ví dụ sau đây : Chương trình tính tổ hợp chập k của n phần tử.
Program Tinh_To_Hop_Chap_K_Cua_N_Phan_Tu;
Uses Crt;
Var n,k: Byte; Tohop : Real;
Procedure Nhap; {Thu tuc nhap du lieu}
Function GT (x : Byte) : Longint; {Ham tinh giai thua}
Var i : Byte; k : Longint;
Begin {Main Program}
Nhap; {Goi thu tuc nhap}
Tohop := GT(n)/(GT(k)*GT(n-k));
{Dung ham GT(n) nhieu lan de tinh to hop chap k cua n phan tu}
Write('To hop chap ',k,' cua ',n,' phan tu la : ',Tohop:0:0);
Readln;
End {Main Program}
- Ta nhận thấy trong chương trình có 2 chương trình con là : Thủ tục Nhap và hàm GT Các chương trình con này có thể gọi nhiều lần trong chương trình
chính Nếu không có hàm GT thì chương trình chính sẽ rất rườm rà vì phải viết 3lần đoạn chương trình tính giai thừa rồi mới gán giá trị cho biến Tohop
2 Cách viết thủ tục và hàm :
Trang 10- Cách viết các chương trình con cũng gần giống như chương trình chính, cũng
có thể có các phần khai báo (biến, hằng,…), thân thủ tục cũng trong cặp từ khóaBegin … End nhưng kết thúc bằng dấu chấm phẩy
3 Sự khác nhau giữa thủ tục và hàm :
- Sự khác nhau cơ bản giũa thủ tục và hàm là ở chỗ : Hàm cho ta kết quả là mộtgiá trị thông qua tên của nó, còn thủ tục thì chỉ thực hiện một khối thao tác màkhông cho kết quả qua tên thủ tục
II TRUYỀN THAM SỐ CHO CHƯƠNG TRÌNH CON :
III BIẾN TOÀN CỤC VÀ BIẾN ĐỊA PHƯƠNG :
IV TÍNH ĐỆ QUY CỦA CHƯƠNG TRÌNH CON :
Trang 11Chương IV : KIỂU DỮ LIỆU CÓ CẤU TRÚC
I KIỂU MẢNG :
1 Khai báo :
- Cách 1 : TYPE <Kiểu mảng> = ARRAY [Chỉ số đầu Chỉ số cuối] OF
<Kiểu phần tử>;
VAR <Biến mảng> : <Kiểu mảng>;
VD : TYPE mangnguyen = ARRAY [1 10] OF Integer;
VAR A,B,C : mangnguyen;
- Cách 2 : VAR <Biến mảng> : ARRAY [Kiểu chỉ dẫn] OF <Kiểu phần tử>;
VD : VAR A,B,C : ARRAY [1 10] OF Integer;
2 Truy nhập vào phần tử mảng :
<Tên mảng> [Chỉ số] {VD: Viết A[5] là truy nhập vào phần tử thứ 5 của mảng A;
3 Duyệt mảng :
Dùng lệnh FOR duyệt qua từng phần tử của mảng để thao tác với phần tử.
VD : For i:=1 to 10 do {Nhập dữ liệu vào mảng A}
Begin
Writeln (‘A[‘,i,’]=’);
Readln (A[i]);
End;
For i:=1 to 10 do Writeln {‘A[‘,i,’]=’,A[i]); {Viết mảng A ra màn hình}
For i:=1 to 10 do C[i]:=A[i]+B[i]; {Gán giá trị cho mảng C}
4 Mảng nhiều chiều (còn gọi là ma trận) :
- Mảng 2 chiều :
Var X,Y,Z : Array [1 3,1 5] Of Integer; {Mảng X,Y,Z gồm 3 hàng, 5 cột}
- Duyệt để truy nhập vào phần tử mảng 2 chiều : Dùng 2 vòng FOR lồng nhau.For i:=1 to 3 do
Trang 12Chương V : MỘT SỐ GIẢI THUẬT THÔNG DỤNG
I GIẢI THUẬT XỬ LÝ SỐ :
1 Kiểm tra số nguyên tố :
Function SNT (x: Word) : Boolean; {Ham kiem tra so nguyen to theo dinh ly}Var p: Integer; f : Boolean;
Procedure SSNT (n: Byte); {Thu tuc sang so nguyen to}
Var TapNT,Sang : Set of Byte;
p,i : Byte;
Begin
TapNT := []; {Tap chua so nguyen to Khoi tao bang rong}
Sang := [2 n]; {Cai sang}
Trang 13If (a=0) and (b<>0) then Begin UCLN:=b; Exit; End;
If (a<>0) and (b=0) then Begin UCLN:=a; Exit; End;
Lưu ý : Tính BCNN(a,b) theo công thức : BCNN(a,b) = a*b div UCLN(a,b))
Function UCLN (a,b : Integer) : Integer; {Thu tuc tim UCLN bang de quy}Begin
Trang 144 Đổi từ cơ số thập phân sang cơ số khác :
II GIẢI THUẬT XỬ LÝ CHUỖI :
1 Đổi chuỗi kí tự thường sang kí tự in hoa :
Trang 151 Phương pháp Thử sai :
Phương pháp thử sai là phương pháp từng bước xem tính chất của đối tượng, nếu đúng thì lưu lại và tiếp tục, nếu sai thì bỏ qua và lùi lại một bước trước đó.
Ví dụ : Lập chương trình xây dựng một dãy gồm N chữ số (N là số nguyênnhập từ bàn phím) từ 3 chữ số cho trước 1, 2, 3 sao cho không có hai dãy con chữ
số liên tiếp nào giống nhau Chẳng hạn, với N=10, ta có dãy 1213123132 là chấpnhận được, còn dãy 1213 121312 là không chấp nhận được; với N=20, ta có dãy
12131231321231213123 là chấp nhận được, còn dãy 121312313 12131231312 làkhông chấp nhận được
Để giải quyết bài toán này, ta dùng một biến chuỗi S lưu trữ dãy đang xâydựng Ta từng bước kiểm tra xem trong chuỗi S có 2 chuỗi con liên tiếp nàogiống nhau hay không Giả sử độ dài chuỗi S (đến thời điểm hiện tại đang kiểm
tra) là m=Length(S) thì 2 chuỗi con liên tiếp cần kiểm tra có độ dài không vượt quá L=m div 2.
Cú pháp : Copy (S : String, P : Integer, N : Integer)
Ý nghĩa : Hàm cho giá trị là xâu ký tự con có N ký tự được lấy ra từ xâu
Trang 16Until (Good and (Length(S)=N)) or (S='');
If Good then Writeln('S=',S) else Writeln('Vo nghiem');
Readln;
End
2 Phương pháp Vét cạn :
Phương pháp vét cạn là phương pháp duyệt qua tất cả mọi trường hợp
có thể xảy ra và chọn lựa xem trường hợp đang xét có thỏa mãn yêu cầu của
đề bài hay không
Ví dụ : Lập chương trình tìm tất cả các số có 3 chữ số abc sao cho tổng các
lập phương của các chử số thì bằng chính số đó Có nghĩa là : abc = a3+b3+c3
Trong trường hợp này, ta sẽ cho máy tính quét hết các khả năng các số có
Trang 17Bài 1 : Lập chương trình tìm tất cả các cách thay thế các dấu chấm hỏi (?)
bởi các dấu phép tính +, -, *, / trong biểu thức dưới dây :
(((((a1 ? a2) ? a3) ? a4) ? a5) ? a6) = a7
Trong đó a1, a2, a3, a4, a5, a6, a7 là số thực nhập từ bàn phím
Bài 2 : Lập chương trình tìm cách điền 9 chữ số khác nhau 1, 2, 3, 4, 5, 6,
7, 8, 9 vào bảng vuông 3x3 sao cho a’b’c’=2a”b”c”=3abc (như hình vẽ dưới)
a b ca’ b’ c’
a” b” c”
V KỸ THUẬT DUYỆT ĐỆ QUY QUAY LUI (BACKTRACKING) :
Kỹ thuật quay lui (Backtracking) như tên gọi của nó, là một quá trình phântích đi xuống Tại mỗi bước phân tích chúng ta chưa giải quyết được vấn đề docòn thiếu cứ liệu nên cứ phải phân tích cho tới các điểm dừng, nơi chúng ta xácđịnh được lời giải của chúng hoặc là xác định được là không thể (hoặc khôngnên) tiếp tục theo hướng này Từ các điểm dừng này chúng ta quay ngược trở lạitheo con đường mà chúng ta đã đi qua để giải quyết các vấn đề còn tồn đọng vàcuối cùng ta sẽ giải quyết được vấn đề ban đầu
Người ta thường sử dụng 3 kỹ thuật quay lui: “vét cạn” là kỹ thuật phải đitới tất cả các điểm dừng rồi mới quay lui “Cắt tỉa Alpha-Beta” và “Nhánh-Cận”
là hai kỹ thuật cho phép chúng ta không cần thiết phải đi tới tất cả các điểmdừng, mà chỉ cần đi đến một số điểm nào đó và dựa vào một số suy luận để cóthể quay lui sớm
Về mặt lý luận, chúng ta có thể phân tích kỹ thuật Quay lui như sau :
Giả thiết một cấu hình cần tìm được mô tả bởi một bộ phận gồm n thànhphần a1, a2, an Giả sử tìm được i - 1 thành phần a1, a2, ai-1, ta tìm thành phầnthứ i bằng cách duyệt tất cả các khả năng có thể của ai Với mỗi khả năng j kiểmtra xem nó có chấp nhận được không Xảy rahai trường hợp :
Nhận được thì xác định ai theo j và kiểm tra xem i = n chưa, nếu i = n thì
ta ghi nhận một cấu hình, còn nếu i < ta gọi tiến hành xác định ai+1
Trang 18Nếu thử tất cả các khả năng mà không có khả năng nào chấp nhận được thìquay lại bước trước xác định lại ai-1
Nội dung của thuật toán này rất phù hợp với việc gọi đệ quy Ta có thủ tục
đệ quy sau đây:
Procedure Try(i: Integer);
Begin
for {mọi giá trị có thể gán cho xi} do
begin
<Thử cho xi := V>;
if (xi là phần tử cuối cùng trong cấu hình) then
<Thông báo cấu hình tìm được>
Else
Begin
<Ghi nhận việc cho xi nhận giá trị V (Nếu cần)>;
Try(i + 1); {Gọi đệ qui để chọn tiếp xi + 1}
<Nếu cần, bỏ ghi nhận việc thử xi := V, để thử giá trị khác>;
end;
end;
end;
Ví dụ : chương trình xếp n quân hậu trên bàn cờ có n*n ô sao cho không quân
nào ăn được quân nào Chẳng hạn, với bàn cờ 8x8=64 ô, ta có một trong 92cách xếp như sau :
Giả sử bàn cờ 4x4, ta làm như sau :
Trang 19Giải: Ta xếp n con hậu trên n dòng, theo nguyên lý nhân ta có nn cách sắp.
Để làm điều đó ta dùng thủ tục đệ quy mô tả ở trên để giải Ta đánh ghi số cột vàdòng của bàn cờ từ 1 đến n, mỗi cách sắp xếp ứng với 1 bộ gồm a1,a2, ,an với ai
= j (j=1,2, ,n) có nghĩa là con hậu thứ i đặt vào cột j Giả sử ta chọn được i-1con hậu bằng cách duyệt tất cả các khả năng của nó
Quan trọng nhất là ta tìm điều kiện chấp nhận j, một con hậu đứng ở một ô trong bàn cờ nó có nhiều nhất bốn hướng đi(đường dọc, đường ngang và hai đường chéo)
Vậy điều kiện chấp nhận thứ i thoả mãn không nằm trên đường đi của tất
cả i-1 con hậu đã xếp Bởi vì n con hậu xếp ở hàng nên đường đi ngang của chúng là không chiến nhau, do đó khi chọn con hậu thư i chỉ cần kiểm tra xem trên 2 đường chéo và đường dọc của chúng có chiếu vào những con hậu đã xếp không? Để kiểm tra điều này mỗi đường ta dùng một biến trạng thái
* Đường dọc kiểm soát bằng biến b[j],(j=1,2, ,n)
* Một đường chéo kiểm soát bằng biến c[i+j],i+j={2, ,2n}
* Còn đường chéo kia kiểm soát bằng biến d[i-j],i-j={1-n, ,n-1}
Các biến trạng thái này khởi gán giá trị True trong thủ tục Init Như vậy
con hậu thứ i được chấp nhận xếp vào cột j nếu nó thoả mãn cả ba biến
b[j],c[i+j],d[i-j] đều có giá trị true Các biến này gán giá trị False khi xếp xong con hậu thứ i, và trả lại giá trị true sau khi gọi Result hay Try(i+1) Ta có chươngtrình Pascal sau :
Program Xep8hau;
Uses Crt;
Const Max=15;
Var x : Array [1 Max] of Integer;
a : Array [1 Max] of Boolean;
b : Array [1 Max*2] of Boolean;
c : Array [-Max Max] of Boolean;