1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Thuat toan lui

16 33 0

Đ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

Cần phải gọi lần lượt một số các rôbôt ra quét vôi (mỗi lần một rôbôt, một rôbôt có thể gọi nhiều lần và có thể có rôbôt không được gọi. Rôbôt được gọi sẽ quét vôi tất cả các phòng mà [r]

(1)

Lê Sỹ Hùng(Sưu Tầm) Hương Sơn Hà Tĩnh

Một tốn liệt kê tổ hợp ln cần phải đảm bảo hai nguntắc, là: khơng bỏ sót cấu hình khơng trùnglặp cấu hình Có thể nói phương pháp liệt kê cách cuốicùng để giải số toán tổ hợp Mộttrong những phương pháp liệt kê có tính phổ dụng cao phươngpháp quay lui

Nội dung phương pháp việc xây dựng dần cácthành phần cấu hình cách thử tất khả Giả thiếtcấu hình cần tìm mơ tả giá trị (x ,x , ,x N ).Giả sử xác định i - thành phần (x ,x , ,x i-1 ),bây

ta xác định thành phần x i cách duyệt tất cảcác khả đề cử cho (đánh

số từ đến n i ).Với khả j, kiểm tra xem j có chấp nhận hay khơng Cóthể

có hai trường hợp xảy ra:

- Nếu j chấp nhận xác định x i theo j, sau j = N ta cấu

hình,trái lại ta tiếptục tiến hành việc xác định x i+1

- Nếu thử tất cảcác khả mà mà khơng có khả chấp nhận ta sẽlùi lại bước trướcđể xác định x i-1

Thơng thường ta phân tích q trình tìm kiếm thành tìm kiếm.Khơng gian tìm kiếm lớn hay nhiều khả tìm kiếm câytìm kiếm lớn, nhiều nhánh Vì hạn chế bỏ bớt cácnhánh vơ nghiệm tìm kiếm tiết kiệm thời gianvà nhớ, tránh bị tràn liệu Quá trình tìm kiếm lời giải theothuật tốn quay lui mơ tả mơ hình tìm dướiđây:

Cần phải lưu ý ta phải ghi nhớ bước qua,những khả thử để tránh trùng lặp Những thông tin nàyđược lưu trữ theo kiểu liệu ngăn xếp - Stack ( vào sau trước) - nên thuật tốn phù hợp thểhiện thủ tục đệ quy Ta mơ tả bước xác định x i thủ tục đệ quy sau:

Procedure Try (i: integer); Var j : integer;

Begin

For j:= 1to ni

(2)

(xác định xi theo j )

if i = N then (ghi nhận cấu hình) else try(i+1);

End; End;

Trong thủ tục mô tả trên, điều quan trọng đưa rađược danh sách khả năngđề cử xác định giá trịcủa biểu thức logic [ chấp nhận j ] Ngoài việc phụ thuộc j, giá trị phụ thuộc vào việc chọn khả i - 1bước trước Trong trường hợp vậy, cần ghi nhớ trạng thái trìnhsau [xác định xi theo j ] vàtrả lại trạng thái cũ sau lời gọi Try(i+1).Các trạng thái ghi

nhận nhờ số biến tổng thể(global), gọi biến trạng thái

Dễ thấy tốn vơ nghiệm ta duyệt hết khảnăng mà khơng có khả thoả mãn yêu cầu Ta nói vét cạn trường hợp.Chú ý đến lúc ta phải lùi liên tiếp nhiều lần.Từ suy rằng, thơng thường tốn vơ nghiệm khơng thể lùiđược Thuật tốn khơng có tính khả thi cao dùng thủtục đệ quy dễ bị lỗi tràn Stack

Bài 1: Hành trình ký tự Cho tệp văn HT_KITU.INP chứa dịng ký tự chiều dài khơngq 32 Hãy lập trình thực cơng việc sau: Lần lượt đọc cácdịng vào xâu, sau từ xâu xây dựng lưới vng dạng tam giácnhư sau: ví dụ xâu =’Vinh’, lưới vng có dạng hình Xuấtphát từ góc trái (chữ V), theo hướng để xâydựng lại xâu cho Với hành trình thành cơng in số thứtự hành trình hành trình lưới, ký tự hànhtrình thay dấu ’*’ Ví dụ:

Sau lời giải phải ấn ENTER để in lời giải tiếp Hướngdẫn giải

Tổ chức hai mảng hai chiều F, Kt[1 32,1 32] of Char.Mảng Kt dùngđể tạo ma trận kí tự dạng tam giác gồm kí tự từ xâuS đọc từ file liệu Mảng F dùng để ghi nhận hành trình thànhcơng, (i,j) thuộc hành trình F[i,j] = ’*’

Sau xây dựng xong ma trận kí tự, ta dùng thủ tục đệ quy Try(i,j,h: byte) để tìm tất hành trình Giả sử ta đangở (i,j) hành trình xâu kí tự độ dài h ≤ length(S ) Nếu h = length(S )thì ta hành trình ta ghi nhận nó, in hìnhhành trình Cịn h < length(S )thì từ (i,j) tasẽ theo hai hướng đến (i,j+1) hoặclà ô (i+1,j) Từmỗi ô ta lại tiếp tục đến khác để tìm hành trình Qtrình tiếp tục thựchiện duyệt hết nghiệm toán

(3)

Vănbản chương trình Program Hanh_trinh_ki_tu; Uses Crt;

Const D : Array[1 2] of shortint= (0,1); C : Array[1 2] of shortint= (1,0); Fi = ’HT_KITU.INP’;

Var Kt,F : Array[1 32,1 32] of Char; S : string;

t : word; dem : longint; Procedure Init; Var k,i,j : byte; G : Text; Begin

Assign(G,Fi); Reset(G); Read(G,S); t:= length(S); Fillchar(F,sizeof(F),’ ’); F[1,1]:=’*’; k:= 0; For i:= to t begin

For j:=1 to t begin

Kt[i,j]:= S[j+k];

If Kt[i,j] = #0 then Kt[i,j]:= ’ ’; end;

inc(k); end; Close(G); End;

Procedure Write_Out; Var i,j : Byte;

Begin Inc(dem);

TextColor(Red); Writeln(’Hanh trinh thu:’,dem); For i:=1 to t

begin

For j:=1 to t If F[i,j]=’*’ then begin

TextColor(White); Write(’* ’) end

(4)

TextColor(Green);Write(Kt[i,j],’ ’); end;

Writeln; end; Readln; End;

Procedure Try(i,j,h: byte); Var k,x,y: byte;

Begin

If h = t then Write_Out else begin

For k:=1 to begin

x:= i + D[k]; y:= j + C[k]; F[x,y]:=’*’;

Try(x,y,h+1); F[x,y]:=’ ’; end; end; End; BEGIN Clrscr; Init; Try(1,1,1); END

Bài 2: Biểu thức zero

Cho số tự nhiên N ≤ Giữa số từ đến N thêm vào cácdấu + - cho kết thu Hãy viết chương trình tìmtất khả

Dữ liệu vào: Lấy từ file văn ZERO.INP với dòng ghi số N Dữ liệu ra: Ghi vào file văn có tên ZERO.OUT có cấu trúc nhưsau: - Dịng đầu ghi sốlượng kết tìm

- Các dịng sau mỗidịng ghi kết tìm Ví dụ

(5)

áp dụng thuật toán đệ quy quay lui để giải toánnay, ta dùng thủ tục đệ quy Try(i) Giả sử ta điền dấu’+’ ’-’ vào số từ đến i, cần điền dấugiữa i i + Ta chọn ba khả năng: điềndấu ’+’, điền dấu ’-’, không điền dấu cả.Khi chọn ba khả trên, ta tiếp tục lựa chọn dấuđể điền vào i + i + cách gọi đệ quy Try(i+1) Ta sẽlần lượt duyệt tất khả để tìm tất nghiệmcủa toán, toán không bị thiếu nghiệm

Nếu i = N ta kiểm tra xem cách điền có thoả mãn kết quảbằng hay không Để kiểm tra ta dùng thủ tục Test chương trình Nếutổng cách điền nghiệm tốn, taghi nhận Nếu i < N tiếp tục gọi Try(i+1) Trong chương trìnhta dùng biến dem để đếm cách điền thoả mãn, mảng M kiểu string ghi nhận cách điền dấu thoả mãn u cầu tốn

Văn chương trình Program Zero_sum;

Type MangStr = array[1 15] of string; Const Fi =’ZERO.INP’;

Fo =’ZERO.OUT’;

Dau : array[1 3] of string[1] = (’-’,’+’,’’);

S : array[1 9] of char =(’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’); ChuSo = [’1’ ’9’];

Var N,k,dem: byte;

D : array[2 9] of string[1]; F : Text;

St : String; M : MangStr;

Procedure Write_out; Var i : byte;

Begin

Assign(F,Fo); Rewrite(F); Writeln(F,dem);

For i:= to dem writeln(F,M[i],’ = 0’); Close(F); Halt;

End;

Procedure Read_inp; Begin

Assign(F,Fi); Reset(F); Read(F,N); Close(F); If N < then write_out; End;

Function DocSo(S : String): longint; Var M : longint;

(6)

Begin M:= 0; t:= 0;

If S[k] in [’+’,’-’] then begin

t:= k; Inc(k); end;

While (k<= length(S)) and (s[k] in ChuSo) begin

m:= m*10 + ord(s[k]) - ord(’0’); Inc(k);

end;

If (t <> 0) and (S[t] = ’-’) then DocSo:= -M else DocSo:= M;

End;

Procedure Test; Var St : string; i : byte;

T : longint; Begin

St:= ’1’; k:= 1; T:= 0;

For i:= to N St:= St + D[i] + S[i];

While k < length(St) + T:= T + DocSo(St); If T = then

begin

Inc(dem); M[dem]:= St; end;

End;

Procedure Try(i: byte); Var j : byte;

Begin

For j:= to begin

D[i]:= Dau[j];

If i = N then Test else try(i+1); end;

End; BEGIN Read_inp; Try(2); Write_out; END

Bài 3: Xổ số điện toán

(7)

một thẻ gồm M ô (đánh số từ đếnM) Người chơi chọn K ô số ô cho cách đánhdấu chọn Sau thẻ đưa vào máy tínhđể xử lý Máy tính chọn K ngẫu nhiên (gọi ô kết quả) chấmđiểm thẻ dựa vào kết sinh Cứ ô chọn vớiô kết thẻ chơi tính điểm Giả thiết biết ôchọn điểm tươngứng thẻ chơi, xác định tất kết cómà máy sinh

Dữ liệu vào đọc từ file vănbản XOSO.INP gồm: - Dòng đầu ghi cácsố N, M, K

- Dòng thứ i trongN dòng tiếp ghi thẻ chơi người i gồm K+1 số: K số đầu sốhiệu

của ôchọn, cuối điểm tương ứng

Ghi kết file văn XOSO.OUT, dòng kết gồmK số ghi số hiệu ô mà máy sinh

Ghi chú:

- Các số mộtdòng file vào/ ra, ghi cách dấu trắng

- Giới hạn kích thước:N ≤ 100, M ≤50, K ≤10

- Dữ liệu vào cáctest hợp lệ đảm bảo có đáp án Ví dụ:

Hướng dẫn giải

Ta nhận thấy rằngmỗi nghiệm tốn cấu hình tổ hợp chập K củaM phần tử Ta áp dụng thuật toán quay lui để duyệt cấu hình tổhợp để tìm cấu hình thoả mãn Tuy nhiên để giảm bớt số lần duyệtta cần phải loại thẻ mà chúng có tổng điểm cầnđánh dấu thẻ chọn

Dùng mảng ok[0 51] of boolean để phân biệt có điểm khơng có điểm Nếu ok[i]= false thìcho biết thẻ thứ i khơng có điểm Cịn logic[i,j] = true cho ta biết người thứ i đánh dấu vàothứ j thẻ

Văn chương trình Program Xoso_dien_toan;

Type MangA = array[0 100,0 11] of byte; MangBool = array[0 51] of boolean;

MangLogic = array[0 101,0 51] of boolean; Cauhinh = array[0 11] of byte;

(8)

B : Cauhinh; Ok : MangBool; Diem : integer; Logic : MangLogic; F : Text;

Procedure Init; Begin

Fillchar(A,sizeof(A),0); Fillchar(B,sizeof(B),0); Fillchar(ok,sizeof(ok),1); Fillchar(logic,sizeof(logic),0); End;

Procedure Read_inp; Var i,j : byte;

Begin

Assign(F,Fi); Reset(F); Readln(F,N,M,K); For i:= to N begin

For j:= to k begin

Read(f,A[i,j]); Logic[i,A[i,j]]:= true; end;

Read(F,A[i,k+1]); Inc(diem,A[i,k+1]); If A[i,k+1] = then

For j:= to k ok[A[i,j]]:= false; end;

Close(F); End;

Function Chapnhan(j: byte): boolean; Var v : byte;

Begin

Chapnhan:= false; For v:= to n

If (A[v,K+1] = 0) and logic[v,j] then exit; Chapnhan:=true;

End;

Procedure Rutgon(j: byte); Var i : byte;

Begin

(9)

begin

Dec(A[i,k+1]);Dec(diem); end;

End;

Procedure Morong(j: byte); Var i : byte;

Begin

For i:= to N If logic[i,j] then begin

Inc(A[i,k+1]); Inc(diem); end;

End;

Procedure Write_out; Var d: byte;

Begin

For d:= to K write(f,B[d],’ ’); Writeln(F); End;

Procedure Try(i:byte); Var j: byte;

Begin

For j:= B[i-1] + to M - K + i If ok[j] and chapnhan(j) then begin

B[i]:= j; Ok[j]:= false; Rutgon(j);

If (diem = 0) and (i = k) then write_out else if i < k then try(i+1);

ok[j]:= true; Morong(j); end; End;

Procedure Run; Begin

Assign(F,Fo); Rewrite(F); Try(1);

(10)

Read_inp; Run; End

Bài 4: Bộ Domino với đồ số

Bộ domino gồm 28 quân đánh số từ đến 28 Mỗi quân hình chữ nhật chia làm hai hình vng Trong người ta ghi số từ (để trống) đến cách trổ dấu tròn trắng Dưới liệt kê 28 quân domino:

Sắp xếp 28 quân domino ta tạo hìmh chữ nhật kích thước 7*8 ô vuông Mỗi cách xếp tạo đồ số Ngược lại, đồ số tương ứng với số cách xếp

Ví dụ đồ số: 4 5 4 1 1 2 2 1 4 6 4 6 3

tương ứng với hai cách xếp mô tả hai bảng số sau: 16 16 24 18 18 20 12 11

(11)

06 06 24 10 10 20 12 11 08 15 15 03 03 17 14 14 08 05 05 02 19 17 28 26 23 01 13 02 19 07 28 26 23 01 13 25 25 07 21 04 27 27 22 22 09 09 21 04

Bài toán đặt cho trước bảnng số, liệt kê tất cách xếp tạo từ

Dữ liệu vào từ file DOMINO.INP ma trận 7*8 mô tả đồ số ban đầu

Kết ghi file DOMINO.OUT dòng đầu số lượng p cách xếp tìm Tiếp theo p nhóm dịng, nhóm gồm dịng ghi dòng bảng tương ứng với bảng số tìm

Hướng dẫn giải

Vói quân domino ta có hai khả xếp vào hình chữ nhật: đặt nằm ngang, đặt nằm dọc Ta thử tất cách để đặt chúng vào hình chữ nhật đặt 28 quân vào hình chữ nhật cách xếp thoả mãn Mỗi cách xếp thoả mãn lưu vào mảng L[1 10,1 7,1 8]

Văn chương trình

Program Bo_bai_domino_voi_cac_ban_do_so; Type Bandoso = array[1 7,1 8] of byte; Sothutu = array[0 6,0 6] of byte; Cauhinh = array[1 10,1 7,1 8] of byte; Const Fi = ’DOMINO.INP’;

Fo = ’DOMINO.OUT’; D : array[1 2] of byte = (0,1); C : array[1 2] of byte = (1,0); Var A,B : Bandoso;

L : Cauhinh; Gt : Sothutu; TS : set of byte; T,dem: byte; F : Text;

Procedure Read_inp; Var i,j,k : byte; Begin

Assign(F,Fi); Reset(F); dem:= 0; For i:= to

begin

For j:= to read(F,A[i,j]); Readln(F);

end;

(12)

begin

Inc(k); Gt[i,j]:= k; Gt[j,i]:= k; end;

Close(F); End;

Function Sott(x: byte) : String; Var S : String;

Begin Str(X,S);

If length(S) = then S:= ’0’ + S; Sott:= S;

End;

Procedure Result; Var i,j : byte; Begin

Inc(dem); For i:= to

For j:= to L[dem][i,j]:= B[i,j]; End;

Procedure Try(i,j : byte); Var k,u,v,x : byte; Begin

While (j < 8) and (B[i,j] > 0) inc(j); If (j = 8) and (B[i,j] > 0) then Try(i+1,1) else For k:= to

begin

u:= i + D[k]; v:= j + C[k];

If (u in [1 7]) and (v in [1 8]) and (B[u,v] = 0) then begin

x:= Gt[A[i,j],A[u,v]]; If not (x in Ts) then begin

Inc(t); Ts:= Ts + [x]; B[i,j]:= x; B[u,v]:= x; If t = 28 then Result else

If v = then Try(i+1,1) else Try(i,v+1); Dec(t); Ts:= Ts - [x];

B[i,j]:= 0; B[u,v]:= 0; end

(13)

Procedure Write_out; Var k,i,j : byte; Begin

Assign(F,Fo); Rewrite(F); Writeln(dem);

For k:= to dem begin

For i:= to begin

For j:= to write(F,Sott(L[dem][i,j]),’ ’); Writeln(F);

end;

Writeln(F); Writeln(F); end;

Close(F); End; BEGIN Read_inp; Try(1,1); Write_out; END

Bài 5: Robot quét vôi

Có phịng (đánh số từ đến 9) quét vôi với mầu trắng, xanh vàng Có rơbơt (đánh số từ đến 9) phụ trách việc qt vơi phịng Mỗi rơbơt qt vơi số phịng định Việc qt vơi thực nhờ chương trình cài sẵn theo qui tắc:

- Nếu phịng có mầu trắng qt mầu xanh, - Nếu phịng có mầu xanh qt mầu vàng, - Nếu phịng có mầu vàng quét mầu trắng

Cần phải gọi số rôbôt quét vôi (mỗi lần rơbơt, rơbơt gọi nhiều lần có rơbơt khơng gọi Rơbơt gọi qt vơi tất phịng mà phụ trách) để cuối phịng có mầu trắng Hãy tìm phương án cho lượng vơi phải qt Giả thiết luợng vơi cho lượt qt phịng

Dữ liệu: đọc từ file văn ROBOT.INP gồm dòng:

- dòng đầu, dịng mơ tả danh sách phịng qt vôi rôbôt theo thứ tự từ rôbôt đến rơbơt Mỗi dịng gồm số hiệu phòng viết sát Chẳng hạn dòng thứ có nội dung: 2356 mơ tả rơbơt phụ trách việc qt vơi phịng 2, 3, 5,

- Dịng cuối mơ tả mầu vơi ban đầu phòng Dòng gồm ký tự viết sát nhau, ký tự thứ i biểu diễn mầu vơi phịng i với quy ước: ký tự T mầu trắng, ký tự X mầu xanh, ký tự V mầu vàng

(14)

- Trái lại ghi dãy thứ tự rôbôt gọi (các số hiệu rơbơt viết sát nhau) Ví dụ

Hướngdẫn giải

Ta giải toán cách duyệt theo tìm kếm Với robot ta không gọi gọi tối đa hai lần, có ba cách lựa chọn Ta duyệt danh sách để gọi robot Vì có tất danh sách nên ta phải duyệt tối đa 39

cách gọi Do tốn địi hỏi lượng vơi nên ta tìm cách gọi tối ưu Để giảm bớt số lần duyệt ta dùng thêm cận để kiểm tra điều kiện có thực tiếp hay không Nếu bước thứ i ta cần gọi S robot số lần gọi tối ưu lúc Min S > ta nhánh quay lại bước thứ i − 1, S < ta tiếp tục đuyệt

Bài 6: Nhà du hành vũ trụ

Một nhà du hành vũ trụ bị lạc vào hành tinh thống trị robot Giả sử hành tinh chia thành mảng hình chữ nhật vng kích thước M X N ( M,N ≤ 8) Tất robot tìm cách tiến lại nhà du hành để tiêu diệt, nhà du hành tìm cách tránh xa robot Cứ sau dơn vị thời gian nhà du hành theo hướng Đông, Tây, Nam, Bắc đứng yên Tất robot lập trình theo hướng kể đường chéo cho khoảng cách từ robot đến nhà du hành nhỏ (khoảng cách không lớn khoảng cách thời điểm trước) đường chéo tính theo cơng thức hình học thơng thường Các robot chuyển động theo nhịp thời gian

Nếu hai robot đến hai robot bị nổ tung để lại nhiệt độ huỷ diệt trì nhiệt độ đủ để phá huỷ robot nhà du hành chẳng may đặt chân lên Ơ trở thành nguy hiểm

Tất robot khơng lập trình để tránh ô nguy hiểm tránh đụng độ mà lập trình để gần nhà du hành cách máy móc

Khi nhiều robot du hành vng nhà du hành bị tiêu diệt Nhà du hành tới có robot

(15)

- Dòng chứa hai số M N,

- Trong M dòng chứa đồ hành tinh: dòng chứa xâu văn (đặt từ đầu dịng) gồm kí tự ’0’, ’1’, ’2’ với ý nghĩa sau:

’0’: ô rỗng ’1’: có robot ’2’: có nhà du hành

Kết in hình ghi vào văn DUHANH.OUT có nội dung sau: - Dòng đầu ghi số đơn vị thời gian nhà du hành tồn hành tinh (quy ước ghi −1 tồn mãi)

- ứng với thời điểm có M dịng file output đồ hành tinh lịch trình, thời điểm cách dịng trống

Ví dụ: Phần đầu lịch trình thể hiên sau:

(16)

Hướng dẫn giải

Sau bước robot gần người thêm dơn vị khoảng cách không gian bị hạn chế thêm đơn vị độ dài chiều rộng lẫn chiều dài, ta đến khẳng định: người tồn sau K = Min{M,N} bước người tồn mãi hay người bị robot ăn thịt khơng thể tồn sau K bước di chuyển.

Với khẳng định lặp không K bước bước lặp liên quan đến việc thực cách bước Như tổng số bước khơng vượt q K thuật tốn.

Ngày đăng: 05/05/2021, 21:55

Xem thêm:

TỪ KHÓA LIÊN QUAN

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

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN

w