Description
我们的主角——老曹陨落于国际象棋棋盘,成为了一位老曹骑士,于是,他开始走“日”字型路线。
在一张N*N的棋盘上,有K只邪恶的河蟹,骑士曹现在要消灭这些河蟹。
要求曹从任意一只河蟹出发,通过他“日”字型的跳跃,到达这K个点至少一次,并最终回到起点。
现在已知棋盘的大小N,和这K只河蟹的位置(棋盘的左上角坐标记为(1,1),右下角坐标记为(N,N)。
询问:曹最少要跳多少步。
Input
第一行:两个整数,N,K(4<=N<=20,1<=K<=10)
接下来K行:每行两个整数X,Y,表示河蟹所在位置。
Output
一个整数,表示曹所需要条的最少步数。
Sample Input
8 3
2 3
4 5
6 7
Sample Output
12
思路:BFS+DFS。。。。。。
pascal:
const
maxn=30;
maxk=10;
type
coordinates=record
x,y:longint;
end;
var
ans:longint;
n,k:longint;
i,j,l:longint;
ender:longint;
bzz:array[0..maxk] of boolean;
coor:array[0..maxk] of coordinates;
bz:array[0..maxn,0..maxn] of boolean;
dist:array[0..maxk,0..maxk] of longint;
data:array[0..maxn*maxn,0..2] of longint;
fx:array[1..8,1..2] of longint=((-2,1),(-1,2),(1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1));
function pdbj(x,y:longint):boolean;
begin
if(x>0)and(x<=n)and(y>0)and(y<=n)then exit(true) else exit(false);
end;
procedure bfs(x,y:longint);
var
i,j,l:longint;
xx,yy:longint;
begin
fillchar(bz,sizeof(bz),true);
fillchar(data,sizeof(data),$7f);
data[1,0]:=0;
data[1,1]:=coor[x].x;data[1,2]:=coor[x].y;
i:=0;j:=1;
while i<j do
begin
inc(i);
for l:=1 to 8 do
begin
xx:=data[i,1]+fx[l,1];yy:=data[i,2]+fx[l,2];
if pdbj(xx,yy) then
if bz[xx,yy] then
begin
inc(j);
bz[xx,yy]:=false;
data[j,1]:=xx;data[j,2]:=yy;
data[j,0]:=data[i,0]+1;
if(xx=coor[y].x)and(yy=coor[y].y)then
begin
dist[x,y]:=data[j,0];
dist[y,x]:=data[j,0];
exit;
end;
end;
end;
end;
end;
procedure dfs(cs,num,last:longint);
var
l:longint;
begin
if(num+dist[last,i]>=ans)then exit;
if(cs>k)then
begin
ans:=num+dist[last,i];
exit;
end;
for l:=1 to k do
if(not bzz[l])then
begin
bzz[l]:=true;
dfs(cs+1,num+dist[last,l],l);
bzz[l]:=false;
end;
end;
begin
fillchar(dist,sizeof(dist),$7f);
readln(n,k);
if k=1 then
begin
writeln('0');
halt;
end;
for i:=1 to k do
begin
with coor[i] do readln(x,y);
dist[i,i]:=0;
end;
for i:=1 to k-1 do
for j:=i+1 to k do
bfs(i,j);
ans:=maxlongint;
for i:=1 to k do
begin
fillchar(bzz,sizeof(bzz),false);
bzz[i]:=true;
dfs(2,0,i);
end;
writeln(ans);
end.
谢谢阅读。