Tải bản đầy đủ (.docx) (10 trang)

mot so kinh nghiem

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (86.23 KB, 10 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

Một số bài toán duyệt


Duyệt đệ quy là một trong những chiến lược để giải quyết nhiều bài toán,
đặc biệt là các bài tốn địi hỏi liệt kê mọi cấu hình thoả mãn. Thuật toán đệ
quy và các vần đề xung quanh đệ quy đã được nhiều tác giả đề cập đến.
Trong bài viết này, tôi cũng sẽ trở lại với chủ đề đệ quy, nhưng là đệ quy
quay lui. Chúng ta sẽ xét một vài bài toán để thấy được sức mạnh của thuật
tốn DUYỆT.


Bài tốn 1:


Có N người tham dự cuộc thi vấn đáp do BB tổ chức. Có tất cả M câu trả
lời.Mỗi người sẽ được BB hỏi K câu.


Sau đó họ sẽ được biết số câu trả lời đúng của mình. Nhưng BB khơng nói
cho họ biết đáp án.


Vốn tị mị nên CC muốn tìm xem đáp án của K câu hỏi như thế nào.
Nhiệm vụ của bạn là giúp CC tìm những đáp án như CC yêu cầu.
Biết rằng:


Đáp án của các câu hỏi không hề trùng nhau


Chỉ cần đua ra bộ đáp án không cần thứ tự trả lời K câu hỏi.
Dữ liệu vào:


D1: N, M, K
N dòng tiếp theo.
Dòng thứ J


Mỗi dòng gồm K+1 số.Số thứ i là số hiệu câu trả lời i của người J


Số cuối cùng là số câu trả lời đúng của người thứ J


Dữ liệu ra:
Gồm 1 số dòng.


Mỗi dòng gồm K số.Số thứ I là đáp án câu hỏi thứ I.
SOLUTION:


Đây là một bài toán khá cơ bản về đệ quy quay lui.


Bạn chỉ cần lập một thủ tục ATTEMP(I) là thủ tục đệ quy tìm đáp án thứ I.
Để cải tiến tốc độ chương trình ta cần một vài cận:


Nếu Result[i] = k thì k phải chưa là đáp án của một câu hỏi nào.
Với giả thiết chỉ cần đưa ra bộ đáp án ta có thêm 1 cận:


Result[i] < Result[j] Nếu i < j.


Thêm một cận nữa là: Những ngươì nào khơng trả lời đúng câu hỏi nào ta
sẽ loại tất cả những câu trả lời của họ ra khỏi đáp án.


</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

Có 9 căn phịng (đánh số từ 1 đến 9) đã được qt vơi với mầu trắng, xanh
hoặc vàng. Có 9 robot (được đánh số từ 1 đến 9) phụ trách việc qt vơi các
phịng. Mỗi robot chỉ qt vơi một số phịng nhất định. Việc qt vơi được
thực hiện nhờ một chương trình cài sẵn theo quy tắc sau:


- Nếu phòng đang có màu trắng thì quét màu xanh.
- Nếu phòng đang có màu xanh thì quét màu vàng.
- Nếu phịng đang có màu vàng thì quét màu trắng.



Cần phải gọi lần lượt một số các robot ra quét vôi (mỗi lần một robot, một
robot có thể gọi nhiều lần và cũng có thể không được gọi. Robot được gọi
quét vôi tất cả các phịng mà nó phụ trách). Hãy tìm một phương án như vậy,
sao cho lượng vơi phải qt là ít nhất. Giả thiết rằng lượng vôi cho mỗi lượt
quét với mỗi phòng là như nhau.


<b>Dữ liệu vào: ROBOT.INP</b>


9 dòng đầu tiên liệt kê danh sách các phòng (viết liền nhau) mà robot thứ i
(i= 1..9) phụ trách.


Dòng cuối mô tả màu vôi ba đầu của các phòng với quy ước:
X- xanh; V − vàng; T - trắng.


<b>Kết quả:</b>


Ghi ra file ″ROBOT.OUT″ gồm 1 dòng dưới dạng:
- Nếu khơng có phương án thì ghi ″0″.


- Ngược lại ghi dãy thứ tự các Robot được gọi.
<b>Ví dụ: </b>


ROBOT.INP
159


123
257
147
5
369


456
789
258


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

1: Màu xanh
2: Màu vàng.


Ta có nhận xét mỗi phịng qt 3 lần thì sẽ trở về màu ban đầu
Hay:


Màu của phịng đó sẽ = số lần qt phịng đó Mod 3 .Gọi Xi1, Xi2, ..Xik là
các robot quét phòng thứ i.


Để phòng thứ I có màu trắng thì: (Xi1 + Xi2 +….+ Xik) Mod 3 = 0.


Chỉ cần quan tâm đến số lần quét phòng i hay số lần các robot có khả năng
qt phịng i qt nó chứ khơng cần quan tâm đến thứ tự gọi các robot ta sẽ
có thuật tốn DUYỆT cấp độ là O(3^9).


BÀI TỐN 3:


Cho xâu kí tự số Number = '123456789'.


Bằng các phép tốn '+' hoặc '-' bạn hãy điền vào xâu Number sao cho:
Sau khi điền xong thực hiện các phép tốn đó ta được kết quả là Rx.
Chỉ yêu cầu tìm một cách hoặc thơng báo là khơng có.


Ví dụ:


Rx = 45 -> 1+2+3+4+5+6+7+8+9


Rx = 125 -> 12+34-5+67+8+9
Rx = 457 -> 12-3 +456-7+8-9
SOLUTION:


Đây là một bài toán khá đơn giản.


Để điền dấu vào xâu ta chỉ cần điền 1 trong 3 loại kí tự sau vào giữa 2 số
liên tiếp trong xâu Number:


1 : '' 2 : '+' . 3 : '-'


Sau khi điền xong ta kiểm tra mất O(9). Có tất cả 8 khe có thể điền ->
Thuật tốn có cấp độ là O(3^8).


BÀI TỐN 4:


Có n tấm phiếu. Mỗi tấm đề có hình dạng là hình vng Trên mỗi tấm phiếu
có k * k ơ hình trịn được đánh dấu.


Các hình trịn đó có thể bị đục thủng mà cũng có thể khơng. Ta được phép
xoay các tấm phiếu đi các góc 90, 180, 270 theo chiều kim đồng hồ.


Tìm cách xoay ít nhất một số tấm phiếu sao cho:


Sau khi xoay các tấm phiếu sẽ tạo thành k * k cột ứng với k * k ơ hình trịn.
Sao cho: Mỗi cột có ít nhất một ô bị đục thủng.


SOLUTION:


Lập thủ tục Attemp(i) là cách xoay tấm phiếu thứ i. Có thể khơng xoay hoặc


xoay 90, 180, 270 độ.


Ta kí hiệu lần lượt là: 0, 1, 2, 3. Thêm một vài cận để tăng tốc độ.


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

Số lần xoay phiếu hiện tại phải nhỏ hơn số lần xoay phiếu đã có


Số ơ bị đục thủng của các tấm phiếu chưa xét phải >= các cột chưa có ơ bị
đục thủng sau khi đã xét i tấm phiếu.


Nếu bạn muốn đặt cận chặt hơn nữa thì xét xem các ơ đó là các ô nào nhưng
làm thế khá là phức tạp có lẽ các cận như thế thì tốc độ của chương trình đã
tạm ổn.


BÀI TỐN 5:


Cho tới nay, Aladdin vẫn cịn sống ở đất nước Iraq đau thương. Toàn bộ gia
sản, trong đó có cả cây đèn thần đã bị chiến tranh hủy hoại. Để nuôi mẹ,
Aladdin lại dệt thảm. Một hôm, anh nhận được một đơn đặt hàng dệt một
tấm thảm hình vng thỏa mãn những điều kiện sau:


- Thảm gồm N dịng và N cột tạo thành N × N ơ vng đơn vị. Các ơ
vng đơn vị có màu đen hoặc trắng.


- Với mỗi hình vng có độ dài cạnh bằng 2, người ta quy định trước số ô
màu đen phải có.


- Người đặt hàng khẳng định đã từng nhìn thấy một tấm thảm như vậy.
Input:<b>ALADDIN.INP</b>


- Dịng đầu ghi số nguyên N.



- N – 1 dòng sau, mỗi dòng ghi N – 1 số trong phạm vi 0..4.


- Số thứ V của dòng thứ U trong N – 1 dịng trên là số ơ đen trong hình
vng gồm 4 ơ (U,V), (U+1,V), (U,V+1), (U+1,V+1).


Output: <b>ALADDIN.OUT</b>


Gồm N dòng, mỗi dòng ghi N số 0 hoặc 1 tương ứng với ơ đó khơng
màu trắng hoặc màu đen. Nếu có nhiều kết quả thỏa mãn, chỉ cần đưa
ra một kết quả duy nhất.


Ví dụ:


<b>ALADDIN.INP</b> <b>ALADDIN.OUT</b>


4
3 2 3
2 3 3
1 2 1


1 1 0 1
1 0 1 1
0 1 1 0
0 0 0 0
Solution:


Gọi Fx(i,j) là số ơ màu đen trong hình vng cạnh bằng 2:
Chứa 4 ô (I,j) (i+1,j) (I,j+1) (i+1,j+1).



</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

A(I,j)=1 nếu ơ(I,j) có màu đen
A(I,j)=0 nếu ơ(I,j) có màu trắng
Hình 1:


Lần duyệt đầu tiên:
Duyệt ơ (1,1):


Khi đó: Fx(1,1) = Fx(1,1) - a(1,1).


Tiến hành duyệt tiếp cặp ơ (1,2) và (2,1).
Hình 2:


Khi đó:


Fx(1,1) = Fx(1,1) - a(1,2).
Fx(1,1) = Fx(1,1) - a(2,1).
Fx(1,2) = Fx(1,2) - a(1,2).
Fx(2,1) = Fx(2,1) - a(2,1).


Sau khi biết 3 ô (1,1) (1,2) (2,1) ta suy ra ô (2,2) bắng công thức:
a(2,2)=Fx(1,1).


Hình 3: Sau khi suy ra ô (2,2).


Tiến hành duyệt cặp ô (1,3) và (3,1).
Hình 4:


Tiếp đó:


Với mỗi ơ (1,3) hoặc (3,1) ta trừ đi các Fx chứa nó.


Tổng qt


Nhận được ơ(i,j) thì:


Các ơ (i,j) (i-1,j) (i,j-1) (i-1,j-1) Phải bị trừ đi một lượng chính bằng a(i,j).
Sau khi biết được 3 ơ (2,1) (3,1) và (2,1) ta suy ra ô (3,2) bằng công thức:
a(3,2) = Fx(2,1).


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

Tương tự suy ra ơ (2,3).
Hình 6:


Rồi từ ơ (2,3) (3,2) (2,2) suy ra ơ (3,3).
Hình 7:


Duyệt cặp ô (1,4) (4, 1)


Ta lần lượt suy ra các cặp ô (2,4) (4, 2)
Rồi từ cặp ô này suy ra tiếp cặp ô (4,3) (3,4)
Tiếp đến suy ra ô (4,4)


Quan sát các hình vẽ:


Dưới đây là từng bước suy ra các cặp ô :


Lời giải tổng quát:


Mỗi khi duyệt cặp ô (1, i) và (i,1) ta sẽ suy ra được hồn tốn hình vng
i*i.


Tập giá trị của cặp ô (1,i) và (i,1) là:


(1,1) or (0,0) or (1,0) or (0,1).


Duyệt ô (i,j) các ô bị giảm giá trị:


4 ô (i,j) (i-1,j) (i,j-1) (i-1,j-1) nếu nằm trong bảng đều bị giảm một lượng
a(i,j).


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

Sau khi duyệt cặp ô (i,1) và (1,i) (i > 1).
-> (2,i) và (i,2)


-> (3,i) và (i,3)
...


Cuối cùng suy ra ơ(i,i).


Cơng thức tính ơ (i,j) là a(i,j) = Fx(i-1,j-1). (i > 1, j > 1).


Sau khi duyệt hết hình vng n*n ta sẽ có lời giải cho bài tốn ALADDIN
Bài tốn 6:


Một tồ nhà gồm có N tầng đánh số từ 1 đến N (N≤100), và chỉ có một
thang máy để phục vụ. Trong một ngày, có tất cả M yêu cầu vận chuyển
bằng thang máy (M≤100), mỗi yêu cầu được mô tả bằng 2 số a, b cho biết
cần vận chuyển hàng từ tầng a đến tầng b. Do yêu cầu vận chuyển nên thang
máy không thể phục vụ 2 yêu cầu cùng một lúc mà phải xong một yêu cầu
mới đến yêu cầu khác. Tuy nhiên người ta có thể thay đổi thứ tự thực hiện
các yêu cầu. Bài toán đặt ra là tìm thứ tự thực hiện các yêu cầu sao cho tổng
quãng đường thang máy phải đi là ít nhất.


Thang máy ban đầu xuất phát từ tầng 1.


<b>Input:</b>


Cho trong file text Elevator.dat :
Dòng đầu là 2 số N, M.


M dòng tiếp theo, dòng thứ i ghi 2 số a, b mô tả yêu cầu thứ i.
<b>Output: </b>


File Elevator.out có cấu trúc:


Dịng đầu là tổng qng đường tìm được.


Dịng thứ hai mơ tả thứ tự thực hiện các yêu cầu bởi một hoán vị của 1, 2,...,
M.


<b>Ví dụ: </b>


<b>INP : OUT :</b>
5 3 9
1 5 - > 1 3 2
3 4


5 2


SOLUTION:


Một trong những cách giải quyết bài toán này là duyệt.
Tuy nhiên là duyệt đặt cận.


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

2 cận chính cho thủ tục duyệt là:



Yêu cầu thứ i chưa được đặt vào các vị trí 1,2,3,...i.


Tổng chi phí khi đặt yêu cầu J vào vị trí i phải nhỏ hơn chi phí hiện tại đặt cả
m yêu cầu.


Thuật tốn có cấp độ cỡ O(n!) tuy nhiên việc đặt cận đã làm tốc độ của
chương trình được cải thiện đáng kể.


Bài tốn 6:


Trên một mảnh sân hình chữ nhật kích thước M * N người ta trồng 2 loại
cây đó là Mai và Đào.Trên sân người ta đã quy định sẵn những ô nào được
phép trồng cây.


Nhiệm vụ của bạn là:


Trồng 2 loại cây Mai hoặc Đào vào các ơ cần trồng cây đó sao cho số cây
Mai và Đào trên mỗi dòng và mỗi cột đều chênh nhau khơng q 1 cây.
Dữ liệu vào:


Dịng 1: M, N
M dòng tiếp theo:


Mỗi dòng gồm N số 1 hoặc 0 để chỉ được phép trồng cây hoặc không được
phép trồng cây.


Dữ liệu ra:
Gồm M dòng.
Mỗi dòng N số



Số 0 chỉ không trồng cây.
Số 1 chỉ trồng cây Mai
Số 2 chỉ trồng cây Đào.
SOLUTION:


Bài tốn này có khá nhiều cách để giải quyết nhưng trong phạm vi bài viết
này tơi sẽ chỉ nói về phương pháp DUYỆT để giải quyết bài tốn.


Lưu các ơ cần duyệt vào một mảng để hạn chế số bước lặp không cần thiết.
Để cho việc duyệt được tốt hơn tại mỗi bước nếu ô trước đó đã đặt cây Mai
thì ơ sau sẽ ưu tiên đặt cây Đào trước như vậy sẽ tối ưu hơn về dịng


Mỗi bước duyệt sẽ có một dịng và một cột có số cây thay đổi ta cần kiểm tra
xemcó thoả mãn điùe kiện bài tốn hay khơng.


Bài tốn chỉ yêu cầu tìm một nghiệm nên khi tìm thấy nghiệm ta sẽ ngắt
chương trình để đảm bảo về mặt thời gian.


Bài tốn 7:


Bản đồ một mê cung hình chữ nhật được chia thành lưới ơ vng kích thước
mxn, trên mỗi ô (i, j) ghi một ký tự aij:


· aij = '.' nếu ơ đó là ơ an tồn


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

"E".


· aij = 'X' nếu đó là ơ nguy hiểm.



Tại mỗi thời điểm, nhà thám hiểm chỉ được di chuyển sang một trong các ơ
an tồn kề cạnh với ô đang đứng.


Yêu cầu: Hãy tìm hành trình di chuyển giúp cho nhà thám hiểm thốt ra một
ơ nằm ở biên của mê cung.


Dữ liệu: Vào từ file văn bản ESCAPE.INP


· Dòng 1: Chứa hai số m, n cách nhau ít nhất một dấu cách (1 £ m, n £ 100)
· m dòng tiếp theo, dòng thứ i chứa n ký tự, ký tự thứ j là aij.


Kết quả: Ghi ra file văn bản ESCAPE.OUT


· Dòng 1: Ghi từ YES hay NO tuỳ theo có tồn tại đường đi thốt khỏi mê
cung hay khơng


· Nếu dịng 1 ghi từ YES, các dòng tiếp theo, mỗi dòng ghi chỉ số hàng và
chỉ số cột của một ơ trong hành trình cách nhau ít nhất một dấu cách. Các ơ
trên đường đi phải được liệt kê theo đúng thứ tự đi qua, bắt đầu từ ô mà nhà
thám hiểm đang đứng tới ơ biên kết thúc hành trình.


Ví dụ:


ESCAPE.IN
P


ESCAPE.OU
T


10 10



XXXXXXX
XXX


XXXXXXX
XXX


XX...XXX
XX.XXX.X
XX


XX.EXX...X
XXXXXX.X
.X


...X.X
XXXXXXX
X.X


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

...X
XXXXXXX
XXX


7 7
7 6
7 5
7 4
7 3
7 2
7 1


SOLUTION:


Đây là một bài tốn đơn giải về tìm đưịng trong ma trận.Thuật toán khá tốt
cho bài toán này là BFS(duyệt theo chiều rộng) với cấp độ ổn định là
O(N^2).


Tuy nhiên ta cũng có thể giải quyết bài tốn này bằng thuật tốn DUYỆT có
tên là DFS (duyệt theo chiều sâu)


Thuật tốn 1 có tinh chất ổn định hơn về mạt thời gian nhưng xét về tình
trạng của Mê cung thì nếu u cầu tìm một nghiệm mê cung có khơng qua
nhiều vật cản thì thuật tốn DFS sẽ đưa ra lời giả trong thời gian nhanh hơn
nếu đi theo một chiều sâu có lợi trong mê cung.


Thuật tốn được miêu tả bởi thủ tục Attemp(I, J) có nghĩa là tìm đường đi ra
biên từ ơ(I, J).


Mỗi bước cần thử đi 4 ô xung quanh:
Attemp(i, j + 1)


Attemp(i + 1, j)
Attemp(i - 1, j)
Attemp(i, j - 1)


</div>

<!--links-->

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×