您的位置:首页 > 其它

[PKU 1915 2243] 搜索之BFS & A*(续)

2010-09-10 21:34 435 查看
{

其实 能用BFS和A*解决的搜索问题很多

比如有一个很simple的骑士巡游问题

就可以这么做

本文只是贴个代码 狗尾续貂 扩充一下

以后有类似的问题也会在这篇文章里补充

}

原题 http://acm.pku.edu.cn/JudgeOnline/problem?id=1915
  //2243与这个题基本类似 注意读入输出的细节

用裸BFS 双向BFS A*皆可

如果用A*

应该自己试着去构造一些启发函数

多多尝试 总有一个最好的

我用的就是很简单的曼哈顿距离作启发

效果不错 值得推荐

但不否认有更好的启发函数 下面贴代码

裸BFS

A*

const    maxq=100000;
maxs=300;
dx:array[1..8]of longint=(1,2,2,1,-1,-2,-2,-1);
dy:array[1..8]of longint=(2,1,-1,-2,-2,-1,1,2);
var    x,y,dep,h,f:array[1..maxq]of longint;
hash:array[0..maxs-1,0..maxs-1]of longint;
n,s,i,gx,gy,hs,qs,tx,ty:longint;
procedure main;
var    i,j,now,temp:longint;
begin
readln(s);
readln(x[1],y[1]);
readln(gx,gy);
if (x[1]=gx)and(y[1]=gy)
then begin
writeln(0);
exit;
end;
fillchar(hash,sizeof(hash),0);
hash[x[1],y[1]]:=1;
hs:=1; h[1]:=1; f[1]:=(abs(gx-x[1])+abs(gy-y[1]))div 3;
qs:=1; dep[1]:=0;
while hs>0 do
begin
now:=h[1];
if (x[now]=gx)and(y[now]=gy)
then begin
writeln(dep[now]);
exit;
end;
h[1]:=h[hs]; f[1]:=f[hs];
dec(hs);
i:=1;
while true do
begin
if i shl 1>hs then break;
if (i shl 1+1>hs)or(f[i shl 1]<f[i shl 1+1])
then begin
if f[i shl 1]<f[i]
then begin
temp:=h[i shl 1]; h[i shl 1]:=h[i]; h[i]:=temp;
temp:=f[i shl 1]; f[i shl 1]:=f[i]; f[i]:=temp;
i:=i shl 1;
end
else break;
end
else begin
if f[i shl 1+1]<f[i]
then begin
temp:=h[i shl 1+1]; h[i shl 1+1]:=h[i]; h[i]:=temp;
temp:=f[i shl 1+1]; f[i shl 1+1]:=f[i]; f[i]:=temp;
i:=i shl 1+1;
end
else break;
end;
end;
for i:=1 to 8 do
begin
tx:=x[now]+dx[i];
ty:=y[now]+dy[i];
if (tx<0)or(tx>s-1)or(ty<0)or(ty>s-1)or(hash[tx,ty]>0)and(dep[hash[tx,ty]]<=dep[now]+1) then continue;
inc(qs);
x[qs]:=tx; y[qs]:=ty;
dep[qs]:=dep[now]+1;
hash[tx,ty]:=qs;
inc(hs);
h[hs]:=qs;
f[hs]:=dep[qs]+(abs(gx-x[qs])+abs(gy-y[qs]))div 3;
j:=hs;
while j>1 do
begin
if f[j shr 1]>f[j]
then begin
temp:=h[j shr 1]; h[j shr 1]:=h[j]; h[j]:=temp;
temp:=f[j shr 1]; f[j shr 1]:=f[j]; f[j]:=temp;
j:=j shr 1;
end
else break;
end;
end;
end;
end;
begin
assign(input,'knight.in'); reset(input);
assign(output,'knight0.out'); rewrite(output);
readln(n);
for i:=1 to n do main;
close(input); close(output);
end.


(未完待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: