题意:
已知国际象棋中骑士得走法(如图),。现给定棋盘大小与起始位置,问一个骑士从起点走到终点,至少需要多少步?
思路:
BFS。一般要求最少步数用广搜。由于问的是最少步数,而且又是棋盘遍历题,所以优先考虑BFS。对于一个点,扫描其8个方向,若该方向上的下一个点未走过,则将该点入队,标记。最终就是检验一下最终步数即可。由于是广度优先,所以第一次找到得步数一定是最小的。
代码:
#include <bits/stdc++.h>
using namespace std;
struct point //建立结构体,存储坐标点和移动的步数
{
int x,y;
int moves;
};
queue<point>q;//建立队列
intex,ey,l;
int map1[305][305];
int dir[8][2]={-1,-2,1,-2,-2,-1,2,-1,-2,1,2,1,-1,2,1,2};//8个方向遍历
int bfs(point s) //广搜
{
int i;
map1[s.x][s.y]=1;
point head,t;
q.push(s);
while(!q.empty()) //基本套路
{
head=q.front();
q.pop();
if(head.x==ex&&head.y==ey)
return head.moves;
for(i=0;i<8;i++)
{
int x=head.x+dir[i][0];
int y=head.y+dir[i][1];
if(x>=0&&x<l&&y>=0&&y<l&&!map1[x][y])
{
map1[x][y]=1;
t.x=x;
t.y=y;
t.moves=head.moves+1;
q.push(t);
}
}
}
}
int main()
{
int n,i,j,ans;
int sx,sy;
point start;
cin>>n;
while(n--)
{
cin>>l;
cin>>sx>>sy>>ex>>ey;
for(i=0;i<l;i++)
for(j=0;j<l;j++)
map1[i][j]=0;
while(!q.empty()) //清空队列
q.pop();
start.x=sx;
start.y=sy;
start.moves=0;
ans=bfs(start);//从起点开始搜索,一直到终点!
cout<<ans<<endl;
}
return 0;
}
心得:
这个题包含了广搜得一些基本套路,可以当做一些题目得模板来使用,此类题目(即从起点到终点最小步数)基本上可以解决,看到求最值,或有棋盘遍历得问题,一般首先想到广搜来解决,先找到的一定是最小得。