新迷宫问题(蛮力法)

已知NxN的迷宫,求指定入口到指定出口的最短路径及其长度。

假设最短路径是唯一的。

和一般的迷宫问题不同,新迷宫只允许从当前位置向左上、右上、右下和左下下这4个方向移动。

输入要求
首先输入一个整数n(0<n<10),然后输入n行字符串,每个字符串由n个O或X组成,代表一个nxn的迷宫,其中O代表通路,X代表障碍。

最后输入4个整数x1, y1, x2, y2,其中(x1, y1)代表入口的位置,(x2, y2)代表出口的位置,并且0<=x1,y1,x2,y2<n

详见输入样例

输出要求
最短路径长度及最短路径

详见输出样例
输入:
OOOO
OXOX
OOXX
OOOO
0 3 3 0
输出:
3
0 3
1 2
2 1
3 0
主要的思路:
使用广度优先遍历算法,过程有点懵逼,主要是对于广度优先遍历的不熟悉,以及对于如何存储最短路径有疑惑。仔细略读之后,发现整个过程就是用一个队列来对最短路径进行存储,由于使用的是广度优先遍历,所以直接检索出来的是最短路径,那么如何用队列来存储呢?定义一个结构体Position,x,y存储位置,pre表示此方块的前一个的下标,因为广度优先遍历是先遍历当前方块下可连接的所有方块,举个例子就是一个人他有很多儿子一样,儿子又有很多儿子,但共同特定是儿子会根据爸爸的姓去找他的爸爸,再去找他的爷爷。即当找到终点方块的时候根据pre 来在队列中找到对应的结构体positon,在从结构体中找pre 一路递推到起点,这就是这道题目的解法。

using namespace std;
int H[8]={0,1,1,1,0,-1,-1,-1};//水平横移量
int V[8]={1,1,0,-1,-1,-1,0,1};//垂直横移量
struct Position{
    int x,y;   //当前方块的位置
    int pre;        //前驱方块de小表
};
void printa(int k);
char num[10][10];
int n,x1,x2,y1,y2;
Position qu[100];  //定义一个队列
int front=-1,rear=-1;//定义一个对头和队尾
void BFS(int x,int y);
void dispath();
int main() {
    cin>>n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin>>num[i][j];
        }
    }
    cin>>x1;
    cin>>y1;
    cin>>x2;
    cin>>y2;
    BFS(x1,y1);
    return 0;
}
void dispath(){
    int number=-1;
    int k1=front;
    while(k1!=-1){
        number++;
        k1=qu[k1].pre;
    }
    cout<<number<<"\n";
    int k=front;
    printa(k);
}
void printa(int k){
    if(k==-1){
        return;
    } else{
        printa(qu[k].pre);
        cout<<qu[k].x<<" "<<qu[k].y<<"\n";
    }
}
void BFS(int x,int y){
    Position p,p1,p2;
    p.x=x;
    p.y=y;
    p.pre=-1;
    num[p.x][p.y]='*';
    rear++;
    qu[rear]=p;
    while(front!=rear){
        front++;
        p1=qu[front];
        if(p1.x==x2&&p1.y==y2){
            dispath();
            return;
        }
        for(int k=0;k<8;k++){
            p2.x=p1.x+H[k];
            p2.y=p1.y+V[k];
            if(p1.x==x2&&p1.y==y2){
                dispath();
                return;
            }
            if (p2.x>=0&&p2.y>=0&&p2.x<n&&p2.y<n&&num[p2.x][p2.y]=='O'){
                num[p2.x][p2.y]='*';
                p2.pre=front;
                rear++;qu[rear]=p2;
            }
        }
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值