总结:
先找到进入floodfill的条件
然后加入把起点加入队列并进行标记
只要队列不空就对格子进行扩展(要除去自己因为自己已经被覆盖过了)
然后判定是否有效(是否超出范围,是否已经覆盖或者是石头)
把扩展的点加入队列并进行标记
然后从已经加入的队列里的数随机选一个再次进行扩展
举例:(9,9)−>(8,8)
pre[8][8]=(9,9)
#include<iostream>
#include<cstring>
using namespace std;
const int N=1010;
#define x first
#define y second
typedef pair<int,int>PLL;
PLL p[N*N];
PLL pre[N][N];//记录上一步的路径(状态表示有没有搜过)
int g[N][N];
int n;
void bfs(int sx,int sy)//宽搜具有最短路的基本性质(第一次搜到的一定是最短的)
{
int hh=0,tt=0;
memset(pre,-1,sizeof pre);
pre[sx][sy]={0,0};//随便一个点都可以
p[0]={sx,sy};//加入队列
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
while(hh<=tt)
{
PLL t=p[hh++];
for(int i=0;i<4;i++)
{
int a=t.x+dx[i],b=t.y+dy[i];
if(g[a][b]) continue;//是墙
if(a<0||a>=n||b<0||b>=n) continue;//判断是否出界
if(pre[a][b].x!=-1)continue;//如果之前被遍历过的话
p[++tt]={a,b};//加入队列
pre[a][b]=t;//记录上一个状态
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&g[i][j]);
bfs(n-1,n-1);//最后一个点往起点搜
PLL end(0,0);//倒推(从起点往回就是正向路径)
while(true)
{
printf("%d %d\n",end.x,end.y);//先把当前终点输出(倒着输出
if(end.x==n-1&&end.y==n-1) break;//如果已经到终点了
end=pre[end.x][end.y];//记录走过来的路
}
}