跟二维地图原理一样,只不过搜索方向多了,二维只搜8个方向,而三维要搜26个方向。

不懂的看我以前写的文章,这里直接贴代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <windows.h>
#include <cmath>
#include <list>
#include <cstdio> using namespace std; const double LEN=10;
const int MAX=500;
const char ROAD='*';
const char WALL='#';
const char START='0';
const char STOP='1'; typedef struct node
{
node()
{
x=y=z=0;
f=g=h=0;
parent=NULL;
}
int x,y,z;
double f,g,h;
struct node *parent;
} Node; char mmap[MAX][MAX][MAX]; //地图
list<Node*> startList,stopList; //开启列表和关闭列表 int sx,sy,sz,ex,ey,ez; //起点坐标(sx,sy,sz)和终点坐标(ex,ey,ez)
int k,n,m; //高度k,m行n列 //26个方向,三阶魔方模型自己想象一下
int dx[26]= {-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1};
int dy[26]= {0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1};
int dz[26]= {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; //计算两点距离
double getDis(int x1,int y1,int z1,int x2,int y2,int z2)
{
double xx1=x1*LEN+LEN/2.0; //获取中心点坐标
double yy1=y1*LEN+LEN/2.0;
double zz1=z1*LEN+LEN/2.0; double xx2=x2*LEN+LEN/2.0;
double yy2=y2*LEN+LEN/2.0;
double zz2=z2*LEN+LEN/2.0; return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2)+(zz1-zz2)*(zz1-zz2));
} //判断节点是否在列表中
bool in_List(Node *pnode,list<Node*> mlist)
{
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if(pnode->x==(*it)->x&&pnode->y==(*it)->y&&pnode->z==(*it)->z)
return true;
}
return false;
} //从列表中删除节点
bool del(Node *pnode,list<Node*> &mlist)
{
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if(pnode==(*it))
{
mlist.erase(it);
return true;
}
}
return false;
} //向列表中添加节点
void add(Node *pnode,list<Node*> &mlist)
{
mlist.push_back(pnode);
return;
} //从列表中获取f最小的节点
Node* getMin(list<Node*> mlist)
{
double mmin=100000000;
Node *temp=NULL;
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if((*it)->f<mmin)
{
mmin=(*it)->f;
temp=(*it);
}
}
return temp;
} //设置路径
void setRoad(Node *root)
{
while(root->parent!=NULL)
{
if(root->x==ex&&root->y==ey&&root->z==ez)
{
mmap[root->z][root->x][root->y]=STOP;
}
else
mmap[root->z][root->x][root->y]=ROAD;
root=root->parent;
}
} void printRoad()
{
for(int kk=0; kk<k; kk++)
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(mmap[kk][i][j]==ROAD||mmap[kk][i][j]==START||mmap[kk][i][j]==STOP)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
cout<<mmap[kk][i][j]<<" ";
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
cout<<mmap[kk][i][j]<<" ";
}
}
cout<<endl;
}
cout<<endl<<endl;
}
cout<<endl<<endl<<endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
} //搜索
void bfs()
{
startList.clear();
stopList.clear();
Node *preNode = new Node;
preNode->x=sx;
preNode->y=sy;
preNode->z=sz;
preNode->g=0;
preNode->h=getDis(sx,sy,sz,ex,ey,ez);
preNode->f=preNode->g+preNode->h;
preNode->parent=NULL;
add(preNode,startList);
while(!startList.empty())
{
//cout<<"-.-"<<endl;
preNode=getMin(startList);
if(preNode==NULL)
{
cout<<"自动寻路失败"<<endl;
return;
}
del(preNode,startList);
add(preNode,stopList);
for(int d=0; d<26; d++)
{
int cx=preNode->x+dx[d];
int cy=preNode->y+dy[d];
int cz=preNode->z+dz[d]; Node *curNode=new Node;
curNode->x=cx;
curNode->y=cy;
curNode->z=cz;
curNode->g=preNode->g+getDis(cx,cy,cz,preNode->x,preNode->y,preNode->z);
curNode->h=getDis(cx,cy,cz,ex,ey,ez);
curNode->f=curNode->g+curNode->h;
curNode->parent=preNode; if(cx<0||cy<0||cz<0||cx>=m||cy>=n||cz>=k) continue; //越界 或碰墙
else if(mmap[cz][cx][cy]==WALL) continue;
else if(in_List(curNode,startList)||in_List(curNode,stopList)) continue; //在开启或关闭列表 if(cx==ex&&cy==ey&&cz==ez)
{
setRoad(curNode);
printRoad();
return;
}
add(curNode,startList);
}
}
cout<<"自动寻路失败"<<endl;
return;
} int main()
{
while(cin>>k>>m>>n)
{
if(k==0||n==0||m==0) break;
for(int kk=0; kk<k; kk++)
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cin>>mmap[kk][i][j];
if(mmap[kk][i][j]==START)
{
sx=i,sy=j,sz=kk;
}
if(mmap[kk][i][j]==STOP)
{
ex=i,ey=j,ez=kk;
}
}
}
}
bfs();
//printRoad(); }
return 0;
}

  测试样例:

````#```
``###```
``###```
``#`````
``#`##``
``#`#``#
`##`#``#
`###`##`
`##`##`
####`#`` ````#```
``#`#```
``#`#```
``#`````
``#`##``
``#`#``#
`##`#`##
`###`##`
``##`##`
####`#`` ````#```
``#`#```
``#`#```
``#`````
``#`##``
``#`#``#
`##`#``#
`###`##`
``#``##`
####`#`

输出结果:

最新文章

  1. the pipeline of call SNP
  2. PHP Switch case 条件并用实例
  3. node.js环境安装,及连接mongodb测试
  4. [No00005D]如何高效利用GitHub
  5. AJAX学习
  6. ajax 代码
  7. Building nginx from Sources(从源代码安装nginx)
  8. ArrayList源代码深入剖析
  9. ionic+angulajs
  10. SQL 优化,全
  11. Jquery库自带的动画效果方法记录
  12. swoole 弹幕系统
  13. eKing Cloud基础云平台演进之路
  14. linux(五)之vi编译器
  15. deep learning入门:感知机
  16. DateTime?,也是一种类型,代表DateTime或NULL两种类型,在处理空时间时比较有用
  17. 【干货】利用MVC5+EF6搭建博客系统(三)添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController
  18. 解决ERROR - unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type=
  19. 算法笔记_170:历届试题 分糖果(Java)
  20. 递归方式 DOM 解析(parse) XML

热门文章

  1. Git 基础教程 之 解决合并冲突
  2. 【ACM】hdu_zs2_1007_Problem G _201308031028
  3. DLR概念
  4. redis--周边知识点
  5. C#--Task知识点
  6. HDU 5175
  7. POJ 2373
  8. 谈论java中怎样处理高并发的问题
  9. hdu 4586 Play the Dice (概率+等比数列)
  10. Android中验证输入是否为汉字及手机号,邮箱验证,IP地址可用port号验证