算法竞赛入门经典:第六章 数据结构基础 6.11迷宫

来源:互联网 发布:电脑软件维修基础教程 编辑:程序博客网 时间:2024/05/17 04:07
/*迷宫:一个网格迷宫由n行m列单元格组成,每个单元格要么是空地(用1表示),要么是障碍物(用0表示)。你的任务是找一条从起点到终点的最短移动序列,其中UDLR分别表示往上、下、左、右移动到相邻单元格。任何时候都不能在障碍格中,也不能走到迷宫之外。起点和终点保证是空地。n,m<=100。输入:思路:采用bfs算法,设定初始结点和结束结点,它必须要有回溯标记,如果一旦不成功要将之前的标记置为未访问,采用队列来做*//*关键:1 在迷宫问题中不管使用bfs还是dfs算法,都不需要再递归后,将剪枝状态进行回溯,因为一旦遇到墙,说明这条路是不通的,因此标记这个路是已经访问过,后序  不需要再访问,而对于回溯问题,由于若采用当前状态不成功的话,要回溯到上一个状态,而当前状态后续中还有可能被用到,因此需要改变状态2 bfs一定是最优问题,所以不要考虑是不是最优解,输出的一定是最优解,因为无效解已经被排除了3 if(iNextX == iEx && iNextY == iEy)//如果抵达终点,直接返回,放在最后判断,不影响递归{return newStat.time;}*/#include <stdio.h>#include <stdlib.h>#include <queue>#define MAXSIZE 50using namespace std;typedef struct Stat{Stat(int _x,int _y,int _time):x(_x),y(_y),time(_time){}int x,y;int time;}Stat;int go[][2] = {{0,1},{1,0},{0,-1},{-1,0}};queue<Stat> queueStat;int iMap[MAXSIZE][MAXSIZE];int iMark[MAXSIZE][MAXSIZE];int iBx,iBy;int iEx,iEy;int N,M;bool isFind = false;int bfs()//返回所耗时间{while(!queueStat.empty()){Stat stat = queueStat.front();queueStat.pop();for(int i = 0 ; i < 4 ; i++){int iNextX = stat.x + go[i][0];int iNextY = stat.y + go[i][1];if(iNextX < 0 || iNextX >= N || iNextY < 0 || iNextY >= M)//越界{continue;}if(iMark[iNextX][iNextY])//已经被访问过{continue;}if(!iMap[iNextX][iNextY])//如果是墙,1表示路,0表示墙,最后的终点必须是路为1{continue;}Stat newStat(iNextX,iNextY,stat.time+1);iMark[iNextX][iNextY] = 1;//置已经访问标记queueStat.push(newStat);if(iNextX == iEx && iNextY == iEy)//如果抵达终点,直接返回,放在最后判断,不影响递归{return newStat.time;}}}return -1;//如果一直没有找到}int main(int argc,char* argv[]){//int n;scanf("%d %d %d %d",&iBx,&iBy,&iEx,&iEy);scanf("%d %d",&N,&M);for(int i = 0; i < N ; i++){for(int k = 0; k < M;k++){scanf("%d",&iMap[i][k]);}}Stat stat(iBx,iBy,0);memset(iMark,0,sizeof(iMark));iMark[iBx][iBy] = 1;queueStat.push(stat);int iTime = bfs();printf("%d\n",iTime);system("pause");return 0;}

0 0
原创粉丝点击