广度优先搜索--迷宫问题(poj 3984)

来源:互联网 发布:用相对坐标编程图例 编辑:程序博客网 时间:2024/05/16 10:44
Language:
迷宫问题
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 25950 Accepted: 15104

Description

定义一个二维数组: 
int maze[5][5] = {0, 1, 0, 0, 0,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0, 1, 1, 1, 0,0, 0, 0, 1, 0,};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 00 1 0 1 00 0 0 0 00 1 1 1 00 0 0 1 0

Sample Output

(0, 0)(1, 0)(2, 0)(2, 1)(2, 2)(2, 3)(2, 4)(3, 4)(4, 4)

Source


#include <iostream>#include <queue>#include <stack>#define NUM 7using namespace std;bool maze[NUM][NUM];bool visted[NUM][NUM];//表示标记;int as[4][2] = {{0,1},{-1,0},{0,-1},{1,0}};//东南西北struct INFO{    int x;    int y;    INFO(){};    INFO(int xx,int yy):x(xx),y(yy){};};INFO pre[NUM][NUM];void BFS(){    queue<INFO> q;    q.push(INFO(1,1));    visted[1][1] = true;    while(!q.empty()){        INFO now = q.front();        q.pop();        for(int i = 0;i<4;i++){            int x  = now.x+as[i][0];            int y = now.y+as[i][1];            if(x==5&&y==5){                visted[x][y] = true;                pre[x][y] = now;                return ;            }            if(!maze[x][y]&&!visted[x][y]){                visted[x][y] = true;                q.push(INFO(x,y));                pre[x][y] = now;            }        }    }}void PrintPath(){        //输出最短路径    INFO temp;         //保存位置    stack<INFO> s;     //保存路径序列    temp.x = 5;    temp.y = 5;    while(temp.x != 1 || temp.y != 1){        s.push(temp);        temp = pre[temp.x][temp.y];    }    cout<<"(0, 0)"<<endl;    while(!s.empty()){        temp = s.top();        cout<<"("<<temp.x-1<<", "<<temp.y-1<<")"<<endl;        s.pop();    }}int main(){    for(int i = 0;i<NUM;i++)        maze[i][0] = maze[i][NUM-1] = maze[0][i] = maze[NUM-1][i] = true;    for(int i = 1;i<NUM-1;i++)        for(int j = 1;j<NUM-1;j++)            cin>>maze[i][j];    BFS();    PrintPath();//    for(int i = 1;i<NUM-1;i++){//        for(int j = 1;j<NUM-1;j++)//            cout <<pre[i][j].x<<pre[i][j].y<<" ";//            cout<<endl;////    }    return 0;}    //需要注意的是,要用pre数组来存放他的父顶点,这里的数组是存放结构体的数组;

//此题也可以用深搜的方法:


#include <iostream>using namespace std;#define NUM 7bool maze[NUM][NUM];bool visted[NUM][NUM];//表示标记;int as[4][2] = {{0,1},{-1,0},{0,-1},{1,0}};//东南西北int result[NUM][NUM];int min_leng = 1<<10;int l;//(0, 0)//(1, 0)//(2, 0)//(2, 1)//(2, 2)//(2, 3)//(2, 4)//(3, 4)//(4, 4)void DFS(int x,int y){    if(x==5&&y==5)        {        if(min_leng>l){            min_leng = l;            for(int i = 1;i<NUM-1;i++){                for(int j= 1;j<NUM-1;j++){                    if(result[i][j]==-1)                    cout<<"("<<i-1<<", "<<j-1<<")"<<endl;                }            }        }        return ;        }    for(int i = 0;i<4;i++){        int a  = x+as[i][0];        int b = y+as[i][1];        if(!visted[a][b]&&!maze[a][b]){            visted[a][b] = true;            result[a][b] = -1;            l++;            DFS(a, b);            l--;            result[a][b] = 0;            visted[a][b] = false;        }    }       }int main(){    for(int i = 0;i<NUM;i++)        maze[i][0] = maze[i][NUM-1] = maze[0][i] = maze[NUM-1][i] = true;    for(int i = 1;i<NUM-1;i++)        for(int j = 1;j<NUM-1;j++)            cin>>maze[i][j];    visted[1][1]= true;    result[1][1] = -1;    DFS(1, 1);    return 0;}



赠送一个可以是任意行和8方向的:


 迷宫问题(八方向) input: 1 6 8 0 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1 0 0 1 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 output: YES (1,1) (2,2) (3,3) (3,4) (4,5) (4,6) (5,7) (6,8) *//*#include<iostream>#include<queue>#include<stack>using namespace std;struct point{        //横坐标纵坐标    int x;    int y;    point(){};    point(int xx,int yy):x(xx),y(yy){};};int row;        //迷宫行数int column;     //迷宫列数bool Maze[100][100];     //初始化迷宫int move_[8][2] ={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};      //移动方向,横竖斜都可以,八个方向point Pre[100][100];    //保存任意点在路径中的前一步bool MazePath(){        //判断是否有路径从入口到出口,保存该路径(队列)    queue<point> q;     //用于广度优先搜索    q.push(point(1,1));    Maze[1][1] = -1;    while(!q.empty()){        point now = q.front();        q.pop();        for(int i=0; i<8; i++){            int t_x =now.x + move_[i][0];            int t_y =now.y + move_[i][1];            if( t_x== row && t_y == column){//结束了;                Maze[t_x][t_y] = -1;                Pre[row][column] = now;                return true;            }            if(Maze[t_x][t_y] == 0){                //下个位置                q.push(point(t_x,t_y));                Maze[t_x][t_y] = -1;                Pre[t_x][t_y] = now;            }        }    }    return false;}void PrintPath(){        //输出最短路径    point temp;         //保存位置    stack<point> s;     //保存路径序列    temp.x = row;    temp.y = column;    while(temp.x != 1 || temp.y != 1){        s.push(temp);        temp = Pre[temp.x][temp.y];    }    cout<<"(1,1)";    while(!s.empty()){        temp = s.top();        cout<<' '<<'('<<temp.x<<','<<temp.y<<')';        s.pop();    }    cout<<endl;}int main(){    int t;          //用例数量    cin>>t;    while(t--){        cin>>row>>column;        memset(Maze, 1, sizeof(Maze));        memset(Pre, 0, sizeof(Pre));        for(int i=0; i<row+2; i++)            Maze[i][0] = Maze[i][column+1] = 1;        for(int j=0; j<column+2; j++)            Maze[0][j] = Maze[row+1][j] = 1;        for(int i=1; i<=row; i++){            for(int j=1; j<=column; j++){                cin>>Maze[i][j];            }        }//输入;        if(MazePath()){            cout<<"YES"<<endl;            for(int i = 0;i<10;i++){                for(int j = 1;j<10;j++)                    cout <<Pre[i][j].x<<Pre[i][j].y<<" ";                cout <<endl;            } PrintPath();        }        else cout<<"NO"<<endl;    }      return 0;  }




原创粉丝点击