题目描述
输入样例
3
001
101
100
1 1 3 3
输出样例
4
AC Code
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int maxn = 1005;
bool m[maxn][maxn];
struct xy{
int x,y,s;
}xy1;
queue<xy> q;
int x1,x2,y1,y2,n;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
void bfs(){
xy1.x = x1,xy1.y = y1,xy1.s = 0;
q.push(xy1);
m[x1][y1] = 1;
while(!q.empty()){
xy t = q.front();q.pop();
if(t.x == x2 && t.y == y2){
cout<<t.s;
return ;
}
for(int i=0;i<4;i++){
int nx = t.x + dx[i],ny = t.y + dy[i];
if((nx>=1&&nx<=n)&&(ny>=1&&ny<=n)&&!m[nx][ny]){
xy t1;
t1.x = nx,t1.y = ny,t1.s = t.s+1;
q.push(t1);
m[nx][ny] = 1;
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
string st;cin>>st;
for(int j=1;j<=n;j++){
m[i][j] = st[j-1]-'0';
}
}
cin>>x1>>y1>>x2>>y2;
bfs();
return 0;
}
解释
〇拿到这道题,计算最短距离,很容易想到需要使用广搜,写完广搜提交代码之后,直接爆了9个MLE,说明空间爆了,需要优化,看了评论区大犇的做法之后,有所感触,写以记之。
①数据结构:bool m[maxn][maxn];
使用m布尔数组,同时存储整张图并判断某个点是否已经路过。输入这张图:
for(int i=1;i<=n;i++){
string st;cin>>st;
for(int j=1;j<=n;j++){
m[i][j] = st[j-1]-'0';
}
}
👆用string变量输入这张图,因为输入是字符串。
判断是否经过,于bfs中:m[nx][ny] = 1;
与m[x1][y1] = 1;
即如果经过了,这个点设置为1(true),没经过,则为0(false)<体现在图中,如果经过了,这个点就成为了障碍,每经过,则是0,以后可以经过>。
②结构体:需要先建立结构体,因为此处的广搜不是遍历图的广搜,一个个输出结点即可。此处的广搜是输出最短路径,因此路径上的每个点都应予以存储于队列中:
struct xy{
int x,y,s;
}xy1;
队列:使用#include <queue>
引用STL队列头文件,再使用queue<xy> q;
建立xy型队列变量q。
广搜:
int dx[] = {0,0,1,-1};//方向数组
int dy[] = {1,-1,0,0};//方向数组
void bfs(){
xy1.x = x1,xy1.y = y1,xy1.s = 0;//第一个结点,优先入列
q.push(xy1);
m[x1][y1] = 1;
while(!q.empty()){
xy t = q.front();q.pop();
if(t.x == x2 && t.y == y2){
cout<<t.s;
return ;
}
for(int i=0;i<4;i++){
int nx = t.x + dx[i],ny = t.y + dy[i];
if((nx>=1&&nx<=n)&&(ny>=1&&ny<=n)&&!m[nx][ny]){
xy t1;
t1.x = nx,t1.y = ny,t1.s = t.s+1;
q.push(t1);
m[nx][ny] = 1;
}
}
}
}
👆没什么好说的,很清晰的思路。
③AC。