Uva 439 - Knight Moves
本题是用bfs实现,模拟马的行走,事实证明深搜的题目是可以用宽搜来做的,而深搜和宽搜的最主要区别就是深搜用栈来实现,而宽搜用队列来实现,然后想象一下栈和队列的调用过程,很简单就可以知道深搜和宽搜的区别。
#include <iostream>
#include<queue>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
/*创建结构体*/
struct Node
{
int x,y,num;//num是计算步数
public:
Node(int a=0,int b=0,int c=0):x(a),y(b),num(c){};
};
int rx,ry;
int d[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};//国际象棋马的移动法则,上下左右一步,斜着一步
int vis[10][10];
/*广度优先搜索*/
int bfs(Node u)
{
queue<Node>q;
q.push(u);//放入起始点
while(!q.empty())//判断非空
{
Node newnode=q.front();//取得起始点
if(newnode.x==rx&&newnode.y==ry)return newnode.num;//返回条件
q.pop();//出栈
/*模拟马的行走*/
for(int i=0;i<8;i++)
{
int dx=newnode.x+d[i][0];
int dy=newnode.y+d[i][1];
if(dx>0&&dx<=8&&dy>0&&dy<=8&&vis[dx][dy]==0)
{
vis[dx][dy]=1;
if(newnode.x==rx&&newnode.y==ry)
return newnode.num;
Node p(dx,dy,newnode.num+1);//num+1是计算
q.push(p);//放入相邻未处理节点
}
}
}
}
int main()
{
char c1,c2;
int d1,d2;
while(cin>>c1>>d1>>c2>>d2)
{
memset(vis,0,sizeof(vis));
rx=c2-'a'+1;
ry=d2;
printf("To get from %c%d to %c%d takes %d knight moves.\n",c1,d1,c2,d2,bfs(Node((int)(c1-'a'+1),d1,0)));
}
}
}
}
广度搜索用队列实现:
广度优先搜索,即BFS(Breadth First Search),是一种相当常用的图算法,其特点是:每次搜索指定点,并将其所有未访问过的邻近节点加入搜索队列,循环搜索过程直到队列为空。
算法描述如下:
(1)将起始节点放入队列尾部
(2)While(队列不为空)
取得并删除队列首节点Node
处理该节点Node
把Node的未处理相邻节点加入队列尾部
使用该算法注意的问题:
(1)使用该算法关键的数据结构为:队列,队列保证了广度渡优先,并且每个节点都被处理到
(2)新加入的节点一般要是未处理过的,所以某些情况下最初要对所有节点进行标记