无边界BFS处理办法

    大家在运用BFS解题时,通常是与一个图结合,这样我们的搜索就有了一个边界(通常是x∈(0,n],y∈(0,m])。但是,如果这个边界没有呢?难道要放弃我们可爱的BFS??

    还是先来看一个例题。

 

【题目描述】
Libojie 在家做物理作业。化学老师Saltless告诉 Libojie 化学元素可以进行多种衰变。α衰变会使原子核裂变出一个氦核(He2+ ,原子核中子数减2质子数减2)。β衰变会使原子核的一个中子放出一个电子后衰变为一个质子。Saltless还告诉 Libojie 原子核可以和氕(一个质子)、氘(一个质子和一个中子)、氚(一个质子和两个中子)进行聚变(即中子数和质子数相加)。现在Saltless让 Libojie 进行原子核的变换,而 Libojie 只有一台粒子碰撞器。Libojie 还想在做完化学作业后学习 IOI 呢!请帮他找出一种方法使得转换的步数最少(一次衰变或一次裂变都算一次转换)。【改编自rqnoj351】

【输入格式】
4个整数A B C D(0<A,B,C,D<200)。分别代表反应物和生成物的质子数和中子数。(友情提示:转换的中间过程A B C D可能会超过200)

【输出格式】
一个整数n(最少的转换步数)。

【样例输入】
5 6 10 15 
【样例输出】
5

 

 

      当时这道题真的囧到我了*.*||| 第一次做的时候傻傻的打了边界 x∈(0,c],y∈(0,d],开始只过了3个点…仔细想想,核子数为什么不能超过目标值呢?完全可以先进行聚变再进行衰变(折腾人家原子核)…

      大家可能注意到ABCD的范围。对,小于200——这是这道题解题的关键。因为数据较小,搜索到略大于200完全可能(较小的数据可能搜不到200就出解)。可以证明,当x,y<203时解就不会有遗漏了。

      所以,当我们遇到边界不明且搜索范围较小时,可以用这种方法。如果边界值不好推算不妨在内存允许的情况下适当加大,避免丢解。

参考代码

 

1 program chram;
2 const
3 dx:array[1..5]of integer=(-2,1,1,1,1);
4 dy:array[1..5]of integer=(-2,-1,0,1,2); //注意不要打错了
5 type l=record
6 x,y:longint;
7 dist:longint;
8 end;
9 var
10 i,j:longint;
11 f,s:longint;
12 d:array[1..100000]of l;
13 a,b,c,dd:longint;
14 xx,yy:longint;
15 v:array[1..300,1..300]of boolean;
16 begin
17 readln(d[1].x,d[1].y,c,dd);
18 f:=1;
19 s:=1;
20 d[1].dist:=0;
21 fillchar(v,sizeof(v),false);
22 v[d[1].x,d[1].y]:=true;
23 while j<=s do //伟大的BFS
24 begin
25 for i:=1 to 5 do
26 begin
27 xx:=d[f].x+dx[i];
28 yy:=d[f].y+dy[i];
29 if(xx>=0)and(yy>=0)and(xx<=203)and(yy<=203)then //传说中的边界
30 if not v[xx,yy] then
31 begin
32 inc(s);
33 d[s].x:=xx;
34 d[s].y:=yy;
35 v[xx,yy]:=true;
36 d[s].dist:=d[f].dist+1;
37 if(xx=c)and(yy=dd)then
38 begin
39 writeln(d[s].dist);
40 close(input);
41 close(output);
42 halt;
43 end;
44 end;
45 end;
46 inc(f);
47 end;
48 writeln('No Sol.'); //自己加的^_^
49 close(input);
50 close(output);
51 end.
 

 

(saltless原创,转载请注明出处)

posted on 2010-08-05 21:41  saltless  阅读(297)  评论(0编辑  收藏  举报

导航