Professional Documents
Culture Documents
Flood Fill
Flood Fill
Loang.inp Loang.out
4 7 2
0 0 1 0 1 1 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
{Phần đệ quy}
Loang(i,j+1); {Loang theo hướng ĐÔNG}
Loang(i,j-1); {Loang theo hướng TÂY}
Loang(i+1,j); {Loang theo hướng NAM}
Loang(i-1,j); {Loang theo hướng BẮC}
End;
{Phần đệ quy}
For i1:=-1 to 1 do
For j1:=-1 to 1 do
If (i1*j1=0) AND (i1+j1<>0) then {Loang 4 hướng}
Loang(i+i1,j+j1);
End;
Cài đặt 3: Cải tiến cài đặt 2 bằng cách sử dụng hằng mảng
Const
dx:array[1..4] of shortint=(-1,0,1,0);
dy:array[1..4] of shortint=(0,-1,0,1);
Procedure Loang(i,j:integer);
Var k:integer;
Begin
{Phần cơ sở}
If a[i,j]<>0 then exit;
If (i<1) OR (i>m) OR (j<1) OR (j>n) then exit;
a[i,j]:=2; { Đánh dấu đã chọn }
{Phần đệ quy}
For k:=1 to 4 do
Loang(i+dx[k],j+dy[k]);
End;
{Phần đệ quy}
For k:=1 to 4 do
Loang(i+dx[k],j+dy[k]);
End;
Procedure LoangBFS(i,j:integer);
Var
qx, qy:queue; {qx: hang doi luu chi so dong,
qy: hang doi luu chi so cot}
head,tail:integer;
x,y,k:integer;
Begin
head:=1; tail:=1;
qx[1]:=i; qy[1]:=j; {Them phan tu vao hang doi}
a[i,j]:=2; {Danh dau da chon}
Repeat
x:=qx[head]; y:=qy[head]; {Lay phan tu dau hang doi}
head:=head+1; {Xoa phan tu khoi hang doi}
For k:=1 to 4 do {Xet 4 O ke voi O(x,y)}
if a[x+dx[k],y+dy[k]]=0 then {Neu co gia tri bang 0}
Begin {Them vao hang doi}
tail:=tail+1;
qx[tail]:=x+dx[k]; qy[tail]:=y+dy[k];
a[x+dx[k],y+dy[k]]:=2; {Danh dau da chon}
End;
Until head>tail; {Hang doi rong}
End;
Cài đặt 2: Ta sẽ không sử dụng biến phụ x, y trong thủ tục LoangBFS, mà sử dụng trực tiếp phần tử đầu hàng
đợi thay cho biến x, y
Const
dx:array[1..4] of shortint=(-1,0,1,0);
dy:array[1..4] of shortint=(0,-1,0,1);
Procedure LoangBFS(i,j:integer);
Var
qx, qy:queue; {qx: hang doi luu chi so dong,
qy: hang doi luu chi so cot}
head,tail:integer;
k:integer;
Begin
head:=1; tail:=1;
qx[1]:=i; qy[1]:=j;
a[x,y]:=2; {Danh dau da chon}
Repeat
For k:=1 to 4 do {Xet 4 O ke voi O(x,y)}
if a[qx[head]+dx[k],qy[head]+dy[k]]=0 then {neu co gia tri 0}
Begin {Them phan tu vao hang doi}
tail:=tail+1;
qx[tail]:=qx[head]+dx[k]; qy[tail]:=qy[head]+dy[k];
a[qx[tail],qy[tail]]:=2; {Danh dau da chon}
End;
head:=head+1; {Xoa phan tu dau hang doi}
Until head>tail; {Hang doi rong}
End;
LOANG 8 HƯỚNG
Nếu miền 0 là tập hợp các ô 0 có chung đỉnh, khi đó từ 1 ô có thể loang đến 8 ô kề với nó.
Theo chiều sâu:
Cài đặt 1: Sử dụng vòng lặp để cải tiến cài đặt 1
Procedure Loang(i,j:integer);
Var i1,j1:integer;
Begin
{Phần cơ sở}
If a[i,j]<>0 then exit;
If (i<1) OR (i>m) OR (j<1) OR (j>n) then exit;
a[i,j]:=2; { Đánh dấu đã chọn }
{Phần đệ quy}
For i1:=-1 to 1 do
For j1:=-1 to 1 do
If (i1<>0) OR (j1<>0) then {Loang 8 hướng}
Loang(i+i1,j+j1);
End;
Cài đặt 2: Cải tiến cài đặt 1 bằng cách sử dụng hằng mảng
Const
dx:array[1..8] of shortint=(-1,0,1,0,-1,1,-1,1);
dy:array[1..8] of shortint=(0,-1,0,1,1,-1,-1,1);
Var a:array[0..max+1, 0..max+1] of integer; {Lưu ý chỉ số bắt đầu từ 0}
Procedure Nhap;
Begin
….
Fillchar(a, sizeof(a),-1);
….
For i:=1 to m do
Begin
For j:=1 to n doRead(fi, a[i,j]);
Readln(fi);
End;
End;
Procedure Loang(i,j:integer);
Var k:integer;
Begin
{Phần cơ sở}
If a[i,j]<>0 then exit;
a[i,j]:=2; { Đánh dấu đã chọn }
{Phần đệ quy}
For k:=1 to 8 do {Loang 8 hướng}
Loang(i+dx[k],j+dy[k]);
End;
BÀI TẬP
Bài 1. RÔ BỐT (Tên file robot.pas)
Miền 0 là tập hợp các ô số 0 có chung cạnh. Một rô bốt chỉ có thể di chuyển trong miền 0. Rô bốt bắt đầu xuất
phát từ ô (x1, y1) và đi đến ô (x2, y2). Hãy lập trình tính số bước di chuyển ít nhất từ ô (x1, y1) đến ô (x2, y2),
và chỉ ra một cách đi như vậy.
Input: File robot.inp, trong đó
• Dòng đầu tiên cho biết số dòng m, số cột n,
• Dòng thứ 2 gồm 4 số nguyên x1, y1, x2, y2
• M dòng tiếp theo biểu diễn bảng ô vuông gồm các số 0 hoặc 1
Output: File robot.out, trong đó
Nếu đi được
• Dòng đầu tiên chứa số k cho biết số bước di chuyển ngắn nhất
• Dòng thứ 2 cho biết cách di chuyển, trong đó
o R: qua phải 1 ô
o D: xuống dưới 1 ô
o L: qua trái 1 ô
o U: lên trên 1 ô
Ngược lại không đi được thì xuất dòng chữ “khong di duoc”
robot.inp robot.out
4 7 4
1 1 3 3 RDDR
0 0 1 0 1 1 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
4 6 khong di duoc
4 4 1 1
0 0 1 1 1 1
0 1 1 1 1 0
0 1 1 0 0 0
0 1 0 0 0 0
BÀI 3. CỜ VÂY
Trên lưới ô vuông tạo thành từ N đường dọc và N đường ngang, hai người lần lượt đặt quân của mình
trên các nút của lưới. Các đường được đánh số từ trên xuống dưới và từ trái qua phải bắt đầu từ 1. Một người
cầm quân đen, người kia cầm quân trắng.
Nhóm quân cùng màu là các quân trên các nút tạo thành một miền liên thông khi chuyển động theo
chiều dọc hoặc ngang. Một quân hoặc nhóm quân cùng màu gọi là bị vây nếu mọi nút kề với các quân này đều
có quân khác màu. Những quân bị vây sẽ bị đối phương ăn (lấy ra khỏi bàn cờ).
Trên hình bên trái có 2 nhóm quân trắng có nguy cơ bị vây. Người cầm quân đen có thể đặt quân của
mình vào vị trí (5,1) và ăn được 3 quân hoặc đặt vào vị trí (4,8) và ăn được 7 quân. Hình bên phải là kết quả
quân đen đặt vào vị trí (4,8).
Yêu cầu: Cho N và cấu hình quân trên bàn cờ. Hãy xác định một vị trí đặt quân đen để có thể ăn được nhiều
quân nhất các quân trắng tại nước đi đó, giả thiết rằng luôn tồn tại ít nhất một nước đi như vậy.
Dữ liệu: Trong file văn bản ENCIRCLE.INP gồm
- Dòng đầu tiên chứa số nguyên N (8 ≤ N ≤ 100).
- N dòng sau, mỗi dòng chứa một xâu N ký tự xác định trạng thái dòng tương ứng của bàn cờ, quân đen được
ký hiệu bằng ký tự b, trắng − w, vị trí trống − dấu chấm ’.’
Chú ý: Không xét những nhóm quân trắng đã bị vây từ trước.
Kết quả: Ra file văn bản ENCIRCLE.OUT một dòng chứa số nguyên M là số quân trắng nhiều nhất có thể ăn
được tại nước đi tiếp theo của quân đen.
Ví dụ: ouput cua bai tren là 7