对BFS的感受
我们在培训基地接触到的第一个名词是DFS,第二个是BFS。后来感触最深的是BFS。
基地培训给一道这样的题:(插图)
看到这一道题时,我就想对于每个房间,我们都需要用相同的方法进行检测,所以用递归去解决或许比较方便。对于那个三维数组的建立,因为要在子函数中操作,我就把它设成静态的数组。刚开始我不知道为什么有的测试用例会通过,后来一想,原来是第一次递归调用时就找到了最短的路径。但由于前面的递归调用影响了数组的数值,后面所操作的数组不再是原来的数组了,也就是说,静态的数组不能进行这样的递归调用。后来也进行过几次修改,但是越改毛病越多。(程序1)
#include<stdio.h>
static int N1,N2,N3,M;
int panduan(int map[100][100][100],int a2,int a3,int a4,int bushu)
{
if(a2==N1-1&&a3==N2-1&&a4==N3-1)
{
if(bushu>M)
bushu=-1;
printf("%d\n",bushu);
return 0;
}
else if(bushu>N1*N2*N3)
{
printf("-1\n");
return 0;
}
else{
if(map[a2][a3][a4]==1)
return 0;
else
{
bushu++; //步数加一
map[a2][a3][a4]=1;
if(a2-1>=0) panduan( map,a2-1,a3,a4,bushu); //向外延伸
if(a2+1<=N1) panduan(map,a2+1,a3,a4,bushu);
if(a3-1>=0) panduan(map,a2,a3-1,a4,bushu);
if(a3+1<=N2-1) panduan(map,a2,a3+1,a4,bushu);
if(a4-1>=0) panduan(map,a2,a3,a4-1,bushu);
if(a4+1<=N3-1) panduan(map,a2,a3,a4+1,bushu);
}
}
}
void main()
{
int i1,map[100][100][100],i,j,k,N;
scanf("%d",&N);
for(i1=0;i1<N;i1++)
{
scanf("%d %d %d %d",&N1,&N2,&N3,&M); //输入地图的大小
for(i=0;i<N1;i++)
{
for(j=0;j<N2;j++)
{
for(k=0;k<N3;k++)
scanf("%d",&map[i][j][k]);
}
}
panduan(map,0,0,0,0);
}
}
周四的时候我看了一川借的一本关于c语言的书,里面讲的有BFS,其中给了一个类似的程序,是一个二维的迷宫问题,我认真地看了一遍,觉得没有必要用递归去解决,普通的循环就能解决。(程序2)
#include<stdio.h>
struct point
{int a1,a2,a3,count;
}queue[100000];
int head=0,tail=0;
static map[100][100][100];
void enqueue(struct point p) //插入队列
{
p.count++;
queue[tail++]=p;
}
struct point dequeue() //从队列取出
{
return queue[head++];
}
void visit(int a1,int a2,int a3,int count) //对该点操作
{
struct point visit_point={a1,a2,a3,count};
map[a1][a2][a3]=1;
enqueue(visit_point);
}
void main()
{
int N,n,i,j,k,X,Y,Z,W;
struct point p;
scanf("%d",&N);
for(n=0;n<N;n++)
{
scanf("%d %d %d %d",&X,&Y,&Z,&W);
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
for(k=0;k<Z;k++)
{
scanf("%d",&map[i][j][k]);
}
}
}
p.a1=0;p.a2=0;p.a3=0,p.count=0;
map[p.a1][p.a2][p.a3]=1;
enqueue(p);
while(head!=tail)
{
p=dequeue();
if(p.a1==X-1&&p.a2==Y-1&&p.a3==Z-1)
break;
if(p.a1-1>=0&&map[p.a1-1][p.a2][p.a3]==0)
visit(p.a1-1,p.a2,p.a3,p.count);
if(p.a1+1<X&&map[p.a1+1][p.a2][p.a3]==0)
visit(p.a1+1,p.a2,p.a3,p.count);
if(p.a2-1>=0&&map[p.a1][p.a2-1][p.a3]==0)
visit(p.a1,p.a2-1,p.a3,p.count);
if(p.a2+1<Y&&map[p.a1][p.a2+1][p.a3]==0)
visit(p.a1,p.a2+1,p.a3,p.count);
if(p.a3-1>=0&&map[p.a1][p.a2][p.a3-1]==0)
visit(p.a1,p.a2,p.a3-1,p.count);
if(p.a3+1<Z&&map[p.a1][p.a2][p.a3+1]==0)
visit(p.a1,p.a2,p.a3+1,p.count);
}
p.count--;
if(p.a1==X-1&&p.a2==Y-1&&p.a3==Z-1)
{
if(p.count>W)
printf("-1\n");
else
printf("%d\n",p.count);
}
else
printf("-1\n");
}
}
(昨天上传错了,那个程序是我参考的刘敏的,这个才是我做的程序)
后来一直纠结的是自己测试的时候都是通过的,然而每次提交都会有错误。所以我认为做编程时和同学的交流是很重要的,这样才能发现自己发现不了的问题。
这次的基地培训感觉收获很大,以后继续努力!