#include<stdio.h> #include<iostream> using namespace std; struct note { int x;//横坐标 int y;//纵坐标 int f;//父亲在队列中的编号,用于求输出路径 int s;//走的步数 }; struct note que[2051]; int i,j,k,n,m,startx,starty,p,q,ty,tx,flag; int a[51][51],book[51][51]; int next[4][2]={{0,1}, {1,0}, {0,-1}, {-1,0}}; /* 如果是八个方向的情况: int next[10][2]={{0,1}, {1,0}, {0,-1}, {-1,0}, {-1,1}, {1,1}, {0,-1} {1,-1}}; for(k=0;k<=7;k++) { //计算下一个点坐标 tx=que[head].x+next[k][0]; ty=que[head].y+next[k][1]; */ void print(int i){ if(que[i].f!=-1){ print(que[i].f); cout<<"("<<que[i].x<<","<<" "<<que[i].y<<")"<<endl; } } void bfs() { //队列初始化 int head=1; int tail=1; //往队列插入迷宫的入口坐标 que[tail].x=startx; que[tail].y=starty; que[tail].f=-1; que[tail].s=0; tail++; book[startx][starty]=1; flag=0;//用来标记是否到达目的地,0表示没有 while(head<tail)//当队列不为空时候 { //枚举四个方向(注意方向数组的设置和for循环的遍历,通用模板) for(k=0;k<=3;k++) { //计算下一个点坐标 tx=que[head].x+next[k][0]; ty=que[head].y+next[k][1]; //判断是否越界 if(tx<1||tx>n||ty<1||ty>n) continue; //判断是否是障碍物或者已经在路径中 if(a[tx][ty]==0&&book[tx][ty]==0) { //把这个点标记为已经走过 //注意宽带搜索每个点只能入队列一次 ,和dfs不同,所以book的值不需要恢复为0; book[tx][ty]=1; //插入新的点到队列中 que[tail].x =tx; que[tail].y=ty; que[tail].f=head;//因为这个点是从head扩展出来的,所以他的父亲是head,由于本题不要求路径,因此本句话可以省略 que[tail].s=que[head].s+1; tail++; } //如果到了目的地,停止扩展,任务结束,退出循环 if(tx==p&&ty==q) { //注意这两句话千万位置不能颠倒 flag=1; cout<<"(1, 1)"<<endl; print(head); break; } } if(flag==1) break; head++;//这个地方千万不能忘记,当一个点扩展结束后,head++才能使得后面的点再进行扩展 } //打印队列中末尾最后一个点的步数 //注意tail是指向队尾的下一个位置,所以需要-1 cout<<que[tail-1].s; } int main() { cin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=m;j++) cin>>a[i][j]; cin>>startx>>starty>>p>>q; bfs(); return 0; }