思想:与二位迷宫问题处理思想类似,基于一点向空间6个方向进行扩展,通过广度优先搜索来取到最短路径。(下面一图可以清楚解释为什么要用广度优先搜索)
通过该图可以清楚的知道,迷宫的路径可能有多个,多条,广度优先总是从距离近到远进行遍历,所以可以达到搜索出最短路径。
/*
3维空间
迷宫问题
*/
int go[][3]
{
1,0,0,
-1,0,0,
0,1,0,
0,-1,0,
0,0,1,
0,0,-1
};
int maze[30][50][50];
bool mark[30][50][50];
struct N
{
int pre;
int x,y,z;
int time;//时间,也就是最少要走多少步
}path[333];
void print3(int i) //当前节点
{
if (path[i].pre != -1) //找到前面那个节点
{
print3(path[i].pre);
cout << "(" << path[i].x << "," << path[i].y <<","<<path[i].z<< ")" << endl;
}
else //最前面的那个节点
{
cout << "(" << path[i].x << "," << path[i].y <<","<<path[i].z<< ")" << endl;
}
}
int BFS(int a,int b,int c)
{
while(front<rear)//队列不空时循环
{
for(int i=0; i<6;i++)
{
int pathX = path[front].x + go[i][0];
int pathY = path[front].y + go[i][1];
int pathZ = path[front].z + go[i][2];//从6个方向一次遍历
if(pathX<0||pathX>=a||pathY<0||pathY>=b||pathZ<0||pathZ>=c)
continue;//越界
if(maze[pathX][pathY][pathZ] == 1)//樯
continue;
if(mark[pathX][pathY][pathZ])
continue;//访问过了
//访问该点
mark[pathX][pathY][pathZ] = true;//设置该点已经被访问过了
path[rear].x = pathX;
path[rear].y = pathY;
path[rear].z = pathZ;
path[rear].pre = front;
path[rear].time = path[front].time+1;//更新时间
rear++;
if(pathX == a-1&&pathY == b-1&& pathZ == c-1)//找到终点
{
print3(rear-1);
return path[rear-1].time;
}
}
front++;
}//end while
return -1;//查找失败
}
int main()
{
int a,b,c;//数组的高度
FILE *fp_in = fopen("F:\\Student\\source2.0.txt","r");//从文件读入数据
//FILE *fp_out = fopen("F:\\Student\\result2.1.txt","w");
while(fscanf(fp_in,"%d%d%d%d",&a,&b,&c,&t)!=EOF)
{
for(int i=0; i<a; i++)
for(int j=0; j<b; j++)
for(int k=0; k<c; k++)
{
fscanf(fp_in,"%d",&maze[i][j][k]);
mark[i][j][k] = false;
}
mark[0][0][0] = false;
path[front].x = 0;
path[front].y = 0;
path[front].z = 0;
path[front].pre = -1;
path[front].time = 0;//初始化第一个点
int rec = BFS(a,b,c);
if(rec<=t)
printf("%d\n",rec);
else
printf("-1\n");
}
return 0;
}