一,BFS写代码基本老套路
1,初始化场景,建立与点有关的数据类型和确定角色行走方向。
2,获取起点,终点和布置场景障碍物。
3,建立队列,将起点进队。
4,循环遍历,一个循环遍历角色该步骤的所有可能,符合条件的进队,并做好标记
不符合条件的不进队。
5,找寻最终答案及输出结果。
二,例题
1, 华东交通大学2022年ACM"双基"程序设计竞赛第I题内容
![](https://i-blog.csdnimg.cn/blog_migrate/ce62e51677120e6aa696f4e44899be5b.png)
代码
#include<iostream>
#include<deque>
using namespace std;
int N[105][105]={0};//初始化场景
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};//确定角色行走方向
int n,m,a,b,x,y;
struct pos//建立与点有关的数据类型
{
int x,y,cnt;
pos(int a,int b,int c):x(a),y(b),cnt(c){};
};
int main()
{
cin>>n>>m>>a>>b>>x>>y;//获取起点,终点
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
cin>>N[i][j];//获取数据和布置场景障碍物
N[x-1][y-1]=2,N[a-1][b-1]=3;//标记起点和终点
deque<pos> d;//建立队列
d.push_back(pos(a-1,b-1,0));//将起点进队
while(!d.empty())//循环遍历
{
for(int i=0;i<4;++i)//一个循环遍历角色在某个位置的所有方向
{
int posx=d.front().x+dir[i][0],posy=d.front().y+dir[i][1];
if(posx<n&&posx>=0&&posy<m&&posy>=0&N[posx][posy]==2)
{//找寻最终答案及输出结果
cout<<d.front().cnt+1;
return 0;
}
//符合条件的进队,并做好标记
if(posx<n&&posx>=0&&posy<m&&posy>=0&N[posx][posy]==0)
d.push_back(pos(posx,posy,d.front().cnt+1)),N[posx][posy]=4;
}
d.pop_front();//该点的所有方向已经遍历了
}
cout<<-1;//找不到答案输出-1
return 0;
}
2,2022寒假训练例题A
Problem A. Red and Black Time limit 1000 ms Mem limit 30000 kB OS Linux There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. Write a program to count the number of black tiles which he can reach by repeating the moves described above. Input The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20. There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows. '.' - a black tile '#' - a red tile '@' - a man on a black tile(appears exactly once in a data set) The end of the input is indicated by a line consisting of two zeros. Output For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself). Sample
![](https://i-blog.csdnimg.cn/blog_migrate/c6d9250a255b2c9a613ed3cd01b2acb4.png)
代码
#include<iostream>
#include<deque>
using namespace std;
int dis[4][2]={{1,0},{0,1},{0,-1},{-1,0}};//确定角色行走方向
class point//建立与点有关的数据类型
{
public:
int x;
和int y;
point(int a,int b):x(a),y(b){};
};
int main()
{
int W,H;
int begin_x=0,begin_y=0;
while(cin>>W>>H)
{
if(W==0&&H==0) break;//对于特殊情况的特判
if(W==0||H==0) //对于特殊情况的特判
{
cout<<0<<endl;
continue;
}
int book[25][25]={0};//初始化场景
char N[25][25]={0};//初始化场景
int count=0;
for(int i=0;i<H;++i)
{
for(int j=0;j<W;++j)
{
cin>>N[i][j];
if(N[i][j]=='@') begin_x=i,begin_y=j,book[i][j]=-1;//获取起点
if(N[i][j]=='#') book[i][j]=-2;//布置场景障碍物
}
}
deque<point> d;//建立队列
d.push_back(point(begin_x,begin_y));//将起点进队
while(!d.empty())//循环遍历
{
for(int i=0;i<4;++i)//一个循环遍历角色该步骤的所有可能的方向
{
int tmpx=d.front().x+dis[i][0],tmpy=d.front().y+dis[i][1];
if(tmpx>=0&&tmpx<H&&tmpy>=0&&tmpy<W&&book[tmpx][tmpy]==0)
{
d.push_back(point(tmpx,tmpy));
++count;//符合条件的进队,并做好标记
book[tmpx][tmpy]=count;
}
}
d.pop_front();//出队
}
cout<<count+1<<endl;//输出最终答案与结果
}
return 0;
}
3,2022寒假训练例题C
Description
有一个 n×m 的棋盘,在某个点 (x, y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
Input
输入只有一行四个整数,分别为 n, m, x, y。
Output
一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。
Sample 1
Input Output
3 3 1 1 0 3 2
3 -1 1
2 1 4
#include<iostream>
#include<deque>
using namespace std;
int dis[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};//确定方向
int book[405][405];//初始化场景
struct point//设置与点有关的数据类型
{
int x,y,count;
point(int a,int b,int c):x(a),y(b),count(c){};
};
int main()
{
int n,m,x,y;
cin>>n>>m>>x>>y;//获取起点
--x,--y;
deque<point> d;//建立队列
d.push_back(point(x,y,0));//将起点入队
book[x][y]=-1;
while(!d.empty())//循环遍历
{
for(int i=0;i<8;++i)//一个循环遍历角色该步骤的所有可能
{
int tmpx=d.front().x+dis[i][0],tmpy=d.front().y+dis[i][1];
if(tmpx>=0&&tmpx<n&&tmpy>=0&&tmpy<m&&book[tmpx][tmpy]==0)
{
//符合条件的进队,并做好标记
d.push_back(point(tmpx,tmpy,d.front().count+1));
book[tmpx][tmpy]=d.back().count;
}
}
d.pop_front();
}
//处理并输出最终结果
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
if(book[i][j]==0) printf("%-5d",-1);
else if(book[i][j]==-1) printf("%-5d",0);
else printf("%-5d",book[i][j]);
}
cout<<endl;
}
return 0;
}