lời giải QBBISHOP spoj – VOI06 Quân tượng

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]

 

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *