Nguồn đề bài: http://vn.spoj.com/problems/QBBISHOP/
1. Đề bài QBBISHOP spoj
Xét bàn cờ vuông kích thước n×n. Các dòng được đánh số từ 1 đến n, từ dưới lên trên. Các cột được đánh số từ 1 đến n từ trái qua phải.
Ô nằm trên giao của dòng i và cột j được gọi là ô (i,j). Trên bàn cờ có m (0 ≤ m ≤ n) quân cờ. Với m > 0, quân cờ thứ i ở ô (ri, ci), i = 1,2,…, m. Không có hai quân cờ nào ở trên cùng một ô. Trong số các ô còn lại của bàn cờ, tại ô (p, q) có một quân tượng. Mỗi một nước đi, từ vị trí đang đứng quân tượng chỉ có thể di chuyển đến được những ô trên cùng đường chéo với nó mà trên đường đi không phải qua các ô đã có quân
Cần phải đưa quân tượng từ ô xuất phát (p, q) về ô đích (s,t). Giả thiết là ở ô đích không có quân cờ. Nếu ngoài quân tượng không có quân nào khác trên bàn cờ thì chỉ có 2 trường hợp: hoặc là không thể tới được ô đích, hoặc là tới được sau không quá 2 nước đi (hình trái). Khi trên bàn cờ còn có các quân cờ khác, vấn đề sẽ không còn đơn giản như vậy.
Yêu cầu: Cho kích thước bàn cờ n, số quân cờ hiện có trên bàn cờ m và vị trí của chúng, ô xuất phát và ô đích của quân tượng. Hãy xác định số nước đi ít nhất cần thực hiện để đưa quân tượng về ô đích hoặc đưa ra số -1 nếu điều này không thể thực hiện được.
Input
Dòng đầu tiên chứa 6 số nguyên n, m, p, q, s, t.
Nếu m > 0 thì mỗi dòng thứ i trong m dòng tiếp theo chứa một cặp số nguyên ri , ci xác định vị trí quân thứ i.
Hai số liên tiếp trên cùng một dòng được ghi cách nhau ít nhất một dấu cách.
Output
Gồm 1 dòng duy nhất là số nước đi tìm được
Example
Input:
8 3 7 2 1 4
5 4
3 4
4 7
Output:
3
2. Thuật toán QBBISHOP spoj
Xem mỗi ô (i, j) như là 1 đỉnh của đồ thị. 2 đỉnh (x1, y1) và (x2, y2) có cạnh nối nếu (x1 – y1 = x2 – y2) hoặc (x1 + y1 = x2 + y2), tức là cùng nằm trên 1 trong 2 đường chéo. Sau đó BFS như thường.
3. code tham khảo QBBISHOP spoj
[sociallocker]
const fi='';
nmax=205;
cld:array[1..4] of shortint=(1,1,-1,-1);
clc:array[1..4] of shortint=(1,-1,1,-1);
type
data=longint;
dulieu=record
u,v:data;
end;
var
f:text;
A:array[0..nmax+1,0..nmax+1] of byte;
m,n,s,t,q,p:data;
C:array[0..nmax+1,0..nmax+1] of data;
H:array[0..nmax*nmax] of dulieu;
dau,cuoi:data;
procedure docfile;
var i,j,u,v:data;
begin
assign(f,fi); reset(f);
readln(f,n,m,p,q,s,t);
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
for i:=0 to n +1 do
begin
A[0,i]:=3;
A[n+1,i]:=3;
A[i,0]:=3;
a[i,n+1]:=3;
end;
for i:=1 to m do
begin
readln(f,u,v);
a[u,v]:=2;
end;
close(f);
end;
procedure themvao(x,y:data);
begin
inc(cuoi);
H[cuoi].u:=x;
H[cuoi].v:=y;
end;
procedure layra(var x,y:data);
begin
x:=H[dau].u;
y:=H[dau].v;
inc(dau);
end;
procedure go(x,y,k:data);
var u,v:data;
begin
u:=x;
v:=y;
while a[u,v]<>3 do
begin
if (A[u,v]=0) then
begin
c[u,v]:=c[x,y]+1;
themvao(u,v);
a[u,v]:=1;
end;
if a[u,v]=2 then
exit;
if (u=s) and (v=t) then
begin
writeln(c[s,t]);
readln;
halt;
end;
u:=u+cld[k];
v:=v+clc[k];
end;
end;
procedure bfs;
var i,j,x,y:data;
begin
dau:=1;
cuoi:=0;
themvao(p,q);
a[p,q]:=1;
for i:=1 to n do
for j:=1 to n do
C[i,j]:=0;
while not (dau>cuoi) do
begin
layra(x,y);
for i:=1 to 4 do
go(x,y,i);
end;
if c[s,t]=0 then
writeln('-1');
end;
begin
docfile;
bfs;
end.
[/sociallocker]