题解 P1443 【马的遍历】
此题就是广度优先搜索题再稍加修改即可,再队列不为空时,一直通过第一个元素扩展出其他点
根据广搜的性质,第一个被存入队列的点的步数一定是最小的步数。
那么就可以使用STL自带的队列queue
首先介绍一下queue队列
头文件#include
push(X)将x放入对头
pop()取出对头元素
front()访问对头元素
empty()判断队列是否为空
代码如下
#include<iostream>
#include<queue>
#include<iomanip>
using namespace std;
int square[405][405];//棋盘
bool aim[405][405];//标记数组
int dx[8]={-2,-2,-1,1,2,2,1,-1};
int dy[8]={1,-1,-2,-2,-1,1,2,2};//马走的方向
struct posi
{
int x,y,dep;
}temp;//定义一个结构体存放每个位置以及步数
queue <posi> ans;//定义队列
int main()
{
int n,m,x,y,t=0;
cin>>n>>m>>x>>y;
aim[x][y]=1;//将起点标记为已走
for(int i=1;i<=n;i++)
{
for(int k=1;k<=m;k++)
square[i][k]=-1;
}//全部初始化为-1,若无法到达某个点则值不会改变
square[x][y]=0;//将起点赋值为0
temp.x=x,temp.y=y;
temp.dep=0;
ans.push(temp);//存入起点
while(!ans.empty())//判断队列是否为空
{
int x1,y1;
for(int i=0;i<8;i++)
{
temp.x=ans.front().x+dx[i];
temp.y=ans.front().y+dy[i];
temp.dep=ans.front().dep+1;//下一个点的步数及位置
if(temp.x<=0||temp.y<=0||temp.x>n||temp.y>m||aim[temp.x][temp.y])
continue;//若不符合条件则跳过
aim[temp.x][temp.y]=1;
ans.push(temp); //若成立,则存入队列
}
square[ans.front().x][ans.front().y]=ans.front().dep;//将当前位置的步数记录下来
ans.pop();//取出对头
}
for(int i=1;i<=n;i++)
{
for(int k=1;k<=m;k++)
cout<<left<<setw(5)<<square[i][k];//左对齐输出
cout<<endl;
}
return 0;//结束
}
感谢观看