赞
踩
给定一个N×M 的网格迷宫 G。G 的每个格子要么是道路,要么是障碍物(道路用 1 表示,障碍物用 00表示)。
已知迷宫的入口位置为 (x1,y1),出口位置为 (x2,y2)。问从入口走到出口,最少要走多少个格子。
输入第 11 行包含两个正整数 N,M,分别表示迷宫的大小。
接下来输入一个 MN×M 的矩阵。若 Gi,j=1 表示其为道路,否则表示其为障碍物。
最后一行输入四个整数 x1,y1,x2,y2,表示入口的位置和出口的位置。
输出仅一行,包含一个整数表示答案。
若无法从入口到出口,则输出 -1。
5 5
1 0 1 1 0
1 1 0 1 1
0 1 0 1 1
1 1 1 1 1
1 0 0 0 1
1 1 5 5
8
//dfs() #include <iostream> #define INF 99999999 int a[101][101],vis[101][101]={0};//a储存地图 vis标记走没走过 int n,m,startx,starty,endx,endy,minCount=INF; int nextSpot[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//方向数组 void dfs(int x,int y,int count) {//维护横纵坐标和当前步数 if (count>=minCount) return;//当前步数大于到终点的最小步数就直接结束 if (x==endx&&y==endy) {//到达终点 minCount=minCount<count?minCount:count;//更新最小步数 return; } for (int i=0;i<4;i++) {//循环方向数组 int nextx=x+nextSpot[i][0];//计算下一步的坐标 int nexty=y+nextSpot[i][1]; if (nextx<=0||nexty<=0||nextx>n||nexty>m) continue;//坐标越界直接结束本循环 if (a[nextx][nexty]==1&&vis[nextx][nexty]==0) {//如果该坐标的值是 1(可走)并且没走过 vis[nextx][nexty]=1;//标记走过 dfs(nextx,nexty,count+1);//深搜下一步,步数加一 vis[nextx][nexty]=0;//深搜完取消标记 } } } int main() { cin>>n>>m; for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) { cin>>a[i][j]; } } cin>>startx>>starty>>endx>>endy; dfs(startx,starty,0);//刚开始步数为零 if (minCount==INF) cout<<-1;//没路 else cout<<minCount; return 0; }
//bfs() #include <iostream> #include <queue> using namespace std; struct place { int x;//横坐标 int y;//纵坐标 int count;//到达该节点走过的最小步数 }; int main() { int a[101][101],vis[101][101]={0};//a储存地图 vis标记走没走过 int nextSpot[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//方向数组 int n,m,startx,starty,endx,endy; cin>>n>>m; for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) { cin>>a[i][j]; } } cin>>startx>>starty>>endx>>endy; queue<struct place> que;//定义队列 struct place temp; temp.x=startx; temp.y=starty; temp.count=0; que.push(temp);//将初始坐标放入队列 while (!que.empty()) {//队列为空,停止扩展 struct place nextPlace,front=que.front();//nextPlace:下一坐标,front:当前栈顶元素 for (int i=0;i<4;i++) {//循环方向数组 nextPlace.x=front.x+nextSpot[i][0];//计算下一步的坐标 nextPlace.y=front.y+nextSpot[i][1]; nextPlace.count=front.count+1; if (nextPlace.x<=0||nextPlace.y<=0||nextPlace.x>n||nextPlace.y>m) continue;//坐标越界直接结束本循环 if (vis[nextPlace.x][nextPlace.y]==1||a[nextPlace.x][nextPlace.y]==0) continue;//如果该坐标的值是 0(不可走)或者走过就结束本次循环 if (nextPlace.x==endx&&nextPlace.y==endy) {//走到终点 cout<<nextPlace.count; return 0;//因为深搜特性,第一次找到的是最优解,直接结束程序即可 } que.push(nextPlace);//不是终点就加入队列,等待下一次被扩展 vis[nextPlace.x][nextPlace.y]=1;//标记本坐标已经被扩展 } que.pop();//队头被扩展完,则出队 } cout<<-1;//没找到终点 return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。