广搜的简单应用1015

来源:互联网 发布:centos编译c 编辑:程序博客网 时间:2024/06/06 02:38
总结:这类题大部分都能转化成坐标的型设计进行遍历搜索,都有套路

题意:已知国际象棋中骑士的走法(具体看原图)。现给定棋盘大小与起始位置,问一个骑士从起点走到终点,至少要走几步。

思路:BFS。由于问的是最少步数,而且又是棋盘遍历题,所以优先考虑BFS。对于一个点,扫描其8个方向,若该方向上的下一个点未走过,则将该点入队,标记。最后就是检验一下终点的步数即可。由于是广度优先,所以第一次找到终点时的步数一定是最小的。

代码:

#include<iostream>
#include<queue>
using namespace std;
struct point{

 int x;
 int y;
 int move;
};
queue<point>q;
int e_x,e_y,l;
int map[400][400];
int dir[8][2]={{-2,-1},{-2,1},{-1,2},{-1,-2},{2,1},{2,-1},{1,2},{1,-2}};
int main()
{
 int bfs(point s);
 int n,i,j,ans;
 int s_x,s_y;
 point start;
 cin>>n;
 while(n--)
 {
  cin>>l;//l是正方形的边长
  cin>>s_x>>s_y>>e_x>>e_y;//起始坐标的输入
  for(i=0;i<l;i++)
   for(j=0;j<l;j++)
    map[i][j]=0;//访问控制,未被访问过的都赋值为零
   while(!q.empty())
    q.pop();
  start.x=s_x;
  start.y=s_y;
  start.move=0;
  ans=bfs(start);
  cout<<ans;

 }
 return 0;
}
int bfs(point s)
{
 int i;
 map[s.x][s.y]=1;
 point m,n;
 q.push(s);
 while(!q.empty())
 {
  m=q.front();//将前一对象的值传递
  q.pop();//移除队首元素
  if(m.x==s.x&&m.y==s.y)  return m.move;
  for(i=0;i<8;i++)
  {
     int x=m.x+dir[i][0];
     int y=m.y+dir[i][1];//一次循环移动一个坐标
     if(x>=0&&x<l&&y>=0&&y<l&&!map[x][y])
     {
      map[x][y]=1;
      n.x=x;
      n.y=y;
      n.move=m.move+1;
      q.push(n);
     }
  
  }
 
 }
}

1 0
原创粉丝点击