编程训练[C语言]——从迷宫最短路径了解BFS

迷宫最短路径涉及BFS和队列的使用,本文不用STL实现这道题。

【题目描述】
图片来源于《挑战程序设计竞赛(第2版)》:
编程训练[C语言]——从迷宫最短路径了解BFS_第1张图片

【算法分析】
首先将起点存入队列;

每次先从队列中取出一个点,然后遍历其上下左右四个方向上的非墙壁点(当然同时也要判断四个方向都在正确范围内)。对于每一个被遍历的点,先判断其是不是终点,如果不是,则将此点加入队列,然后处理下一个遍历到的点。对于每个被遍历的点,同时还要存储从开始点到达其的步数,存储结构是一个数组,数组用INF进行初始化。

本题较为麻烦,要进行队列的正确操作,如果用STL还比较简单。但为了锻炼编程能力,博主决定这次不用STL。

【示例代码】

#include

#define MAX_N 100
#define MAX_M 100
#define INF 100000000	//记住这个,INF通常赋值为100000000

//队列存储结构
int queue_x[MAX_N*MAX_M];
int queue_y[MAX_N*MAX_M];
int front,rear;

void enqueue(int x,int y){
    queue_x[rear++]=x;
    queue_y[rear++]=y;
}

int dequeue_x(){
    return queue_x[front++];
}

int dequeue_y(){
    return queue_y[front++];
}

int main(){
    int N,M;
    int step[MAX_N][MAX_M];     //存储起点到当前点的步数,初始化为超大数(代表不可达)
    char map[MAX_N][MAX_M];
    int start_x,start_y;    //存储起点的坐标
    char ch;
    int current_x,current_y;
    
    while(scanf("%d %d",&N,&M)==2){
        getchar();
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
//                scanf("%c",&map[i][j]);	//这样输入也是可以的,博主想试一下getchar()
                ch=getchar();
                if(ch=='S'){    //不要将'S'写成"S"
                    start_x=i;
                    start_y=j;
                }
                map[i][j]=ch;
            }
            getchar();
        }
        
        //初始化step数组
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                step[i][j]=INF;
            }
        }
        
        //初始化队列
        front=0;
        rear=0;
        
        //核心算法
        enqueue(start_x,start_y);   //将起点加入队列
        step[start_x][start_y]=0;
        while(map[current_x=dequeue_x()][current_y=dequeue_y()]!='G'){
            int dx,dy;
//            for(dx=-1;dx<=1;dx++){    //  这种写法是错误的,因为它用来遍历八个方向
//                for(dy=-1;dy<=1;dy++){
            
            for(dx=-1,dy=0;dx<=1;dx+=2){
                int x=current_x+dx;
                int y=current_y+dy;
                if(x>=0&&x<N&&y>=0&&y<M){   //判断未出界
                    if((map[x][y]=='G'||map[x][y]=='.')&&step[x][y]==INF){
                        step[x][y]=step[current_x][current_y]+1;
                        enqueue(x,y);
                    }
                }
            }
            for(dy=-1,dx=0;dy<=1;dy+=2){
                int x=current_x+dx;
                int y=current_y+dy;
                if(x>=0&&x<N&&y>=0&&y<M){   //判断未出界
                    if((map[x][y]=='G'||map[x][y]=='.')&&step[x][y]==INF){
                        step[x][y]=step[current_x][current_y]+1;
                        enqueue(x,y);
                    }
                }
            }
        }
        
        //回答问题
        printf("%d\n",step[current_x][current_y]);
    }
    
    return 0;
}

你可能感兴趣的:(刷点算法题)