1马的遍历
(1)给所有点赋初值为-1这样没被改变的初值就是不能访问到的点
(2)这题都是求到每个点的最短路径就用bfs
#include<iostream>
#include<algorithm>
#include <queue>
using namespace std;
struct node
{
int x,y;
};
node z;
int nex[8][2]={{1,2},{-1,2},{-1,-2},{1,-2},{2,1},{2,-1},{-2,-1},{-2,1}};//马走的八个方向
int m,n;
int x,y;
int coun;
int book[401][401];//标记数组
int ans[401][401];//b2存放个点的步数
void print()//打印答案
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
printf("%-5d",ans[i][j]);
cout << endl;
}
}
void bfs(node x)
{
queue<node>a;
a.push(x);
while(!a.empty())
{
for(int i=0;i<8;i++)//往八个反向走
{
node x1;
x1.x=a.front().x+nex[i][0];
x1.y=a.front().y+nex[i][1];
if(x1.x>0&&x1.x<=m&&x1.y>0&&x1.y<=n&&book[x1.x][x1.y]==0)//能够走且没走过
{
node x2=a.front();
book[x1.x][x1.y]=1;//标记已经走过
ans[x1.x][x1.y]=ans[x2.x][x2.y]+1;//该点的步数等于上一点步数加一
a.push(x1);//入队
}
}
a.pop();//出队,否则死循环
}
print();
}
int main()
{
cin>>m>>n;
cin>>z.x>>z.y;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
ans[i][j]=-1;//将所有步数初始化为-1能够访问到的点都会改变值
book[z.x][z.y]=1;
ans[z.x][z.y]=0;
bfs(z);
}
2奇怪的电梯
(1)此题只可以有上下两个方向,求最短咱就用bfs(bfsyyds),还是跟广搜的模板一样,
只要将判断反向的改一下
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
int x;
int step;
};
queue<node>que;
int s[2000];
bool vis[2000];
int n,a,b;
int bfs()
{
while(!que.empty())
{
node q,h;
q=que.front();
que.pop();
if(q.x==b)return q.step;//找到就返回
int i;
i=q.x+s[q.x];
if(i>=1&&i<=n&&vis[i]==0)//往上走
{
h.x=i;
h.step=q.step+1;
que.push(h);
vis[i]=1;
}
i=q.x-s[q.x];
if(i>=1&&i<=n&&vis[i]==0)//往下走
{
h.x=i;
h.step=q.step+1;
que.push(h);
vis[i]=1;
}
}
return -1;//找不到解
}
int main()
{
cin >> n >> a >> b;
for(int i=1;i<=n;i++)
cin >> s[i];
node c;
c.x=a;
c.step=0;
vis[a]=1;//标记初始位置
que.push(c);//起点入队
cout<< bfs();
}
3一起再看流星雨
又是bfs,但是这题的地图障碍是有时间限制的所以我们将地图上被流星砸的位置标记上时间,但是流星可能会重复砸同一个位置所以我们要对该位置保存最早的时间。
因为该时间是从0时刻开始所以我们对地图初始化为-1
只要我们能走到-1上来就代表我们安全了
***注意初始化地图我在这错了并找了好久才发现 ***
#include<iostream>
#include<algorithm>
#include<string.h>
#include <queue>
using namespace std;
struct node
{
int x,y;
int step;
};
int vis[500][500];//地图
int book[500][500];//标记
int dx[5]={0,0,0,1,-1};//方向数组第一个是为了初始化地图
int dy[5]={0,1,-1,0,0};
int t;
int bfs()
{
queue<node>que;
node q;
q.x=0;q.y=0;q.step=0;
que.push(q);
while(!que.empty())
{
node h=que.front();
if(vis[h.x][h.y]==-1)return h.step;//安全返回
que.pop();
for(int i=1;i<5;i++)//向四面走
{
node z;
z.x=h.x+dx[i];
z.y=h.y+dy[i];
z.step=h.step+1;
if(z.x>=0&&z.x<500&&z.y>=0&&z.y<500)//在范围内
if((z.step<vis[z.x][z.y]||vis[z.x][z.y]==-1)&&book[z.x][z.y]==0)//该时刻小于此点被砸的时刻或者此点安全且此点没有走过
{
que.push(z);//此点入队
book[z.x][z.y]=1;//标记
}
}
}
return -1;//不能到达安全的地方
}
int main()
{
cin >> t;
memset(vis,-1,sizeof(vis));
while(t--)
{
int x,y,t;
cin >>x>>y>>t;
for(int i=0;i<5;i++)
if(x+dx[i]>=0&&x+dx[i]<500&&y+dy[i]>=0&&y+dy[i]<500)//初始化的一定注意自己也可能被炸反要选炸自己最小的
if((vis[x+dx[i]][y+dy[i]]==-1||vis[x+dx[i]][y+dy[i]]>t) )
vis[x+dx[i]][y+dy[i]]=t;
}
book[0][0]=1;//将起点标记
cout << bfs();
}