双向广度优先搜索
其实就是BFS,从初始状态和目标状态同时搜索,什么时候撞上了就是找到了。但是实现起来比较麻烦。我模仿了一个程序写了NOIp2002的子串变换,采用的是节点少的先扩展。然后自己写了POJ1915,但是调试不出来。于是又模仿了一个程序写了交替扩展节点的程序,发现代码能精简不少。
上百行的程序必须注意代码的质量了。否则理解和调试会很麻烦的。
下面是两个程序。
字串变换
{
简单的搜索题,写了一个BFS,5个点过了4个,估计也许是字符串中出现好几个子串都可以变换的情况没有考虑到。另外运行效率不高,或许要写个hash判重。
然后写了一个双向广搜,算是第一个双向广搜程序了。双向广搜一般代码很长,但这题比较简单而且我模仿的这个程序写得还可以,所以不到百行。其实也不难理解,就是实现的时候要掌握好细节。
另外我模仿的这个程序复制字符串的时候都是多复制几位的,但是能AC。貌似PASCAL比较或复制字符串的时候会自动忽略无效的字符。
2011-09-15 23:15
}
type
node=record
s:string;
depth:longint
end;
queue=record
data:array[1..8000] of node;
head,tail:longint;
end;
var
a:array[0..10,0..1] of string;
q:array[0..1] of queue;
i,j,n:longint;
s,temp:string;
function check(s:string; sign:longint):longint;
var
i:longint;
begin
for i:=1 to q[sign].tail do
if q[sign].data[i].s=s then
exit(-1);
for i:=1 to q[1-sign].tail do
if q[1-sign].data[i].s=s then
exit(i);
exit(0);
end;
procedure expand(s:longint);
var
i,j,len,lenx,pos,judge:longint;
x:string;
begin
inc(q[s].head);
x:=q[s].data[q[s].head].s;
len:=length(x);
for i:=1 to n do
begin
lenx:=length(a[i,s]);
for j:=1 to len-lenx+1 do
if copy(x,j,lenx)=a[i,s] then
begin
temp:=copy(x,1,j-1)+a[i,1-s]+copy(x,j+lenx,len);
judge:=check(temp,s);
if (judge<>0) and (judge<>-1) then
begin
writeln(q[s].data[q[s].head].depth+1+q[1-s].data[judge].depth);
halt;
end
else if judge=0 then
begin
inc(q[s].tail);
q[s].data[q[s].tail].s:=temp;
q[s].data[q[s].tail].depth:=q[s].data[q[s].head].depth+1;
end;
end;
end;
end;
begin
while (not eof) and (s<>'I love sry') do
begin
readln(s);
a[n,0]:=copy(s,1,pos(' ',s)-1);
a[n,1]:=copy(s,pos(' ',s)+1,length(s));
inc(n);
end;
dec(n);
if a[0,0]=a[0,1] then
begin
writeln(0);
halt;
end;
for i:=0 to 1 do
begin
q[i].head:=0;
q[i].tail:=1;
q[i].data[1].s:=a[0,i];
end;
while true do
begin
if (q[0].tail=0) and (q[1].tail=0) then
break;
if (q[0].tail<q[1].tail) then
expand(0)
else
expand(1);
if q[0].data[q[0].tail].depth+q[1].data[q[1].tail].depth>10 then
break;
end;
writeln('NO ANSWER!');
end.
POJ1915
{
跳马问题,从一个点到另一个点的最少步数
双向BFS,交替扩展节点。
2011-09-16 22:16
}
const
dx:array[1..8] of longint=(1,1,-1,-1,2,2,-2,-2);
dy:array[1..8] of longint=(2,-2,2,-2,1,-1,1,-1);
var
n:longint;
q:array[0..1000000] of record x,y:longint; end;
flag,step:Array[0..400,0..400] of longint;
t,i,j,k:longint;
head,tail:longint;
function check(x,y:longint):boolean;
begin
if (x>=0)and(y>=0)and(x<n)and(y<n) then
exit(true)
else
exit(false);
end;
procedure main;
var
sx,sy,tx,ty,x,y:longint;
xx,yy:longint;
i,j,k:longint;
begin
readln(n,sx,sy,tx,ty);
if (sx=tx) and (tx=ty) then
begin
writeln(0);
exit;
end;;
fillchar(flag,sizeof(flag),0);
fillchar(step,sizeof(step),0);
flag[sx,sy]:=1;
flag[tx,ty]:=2;
q[1].x:=sx;
q[1].y:=sy;
q[2].x:=tx;
q[2].y:=ty;
head:=0;
tail:=2;
while head<tail do
begin
inc(head);
x:=q[head].x;
y:=q[head].y;
for i:=1 to 8 do
begin
xx:=x+dx[i];
yy:=y+dy[i];
if not check(xx,yy) then continue;
if flag[xx,yy]=0 then
begin
inc(tail);
q[tail].x:=xx;
q[tail].y:=yy;
flag[xx,yy]:=flag[x,y];
step[xx,yy]:=step[x,y]+1;
end
else if flag[xx,yy]<>flag[x,y] then
begin
writeln(step[xx,yy]+step[x,y]+1);
exit;
end;
end;
end;
end;
begin
readln(t);
for i:=1 to t do
main;
end.
浙公网安备 33010602011771号