普通bfs:
//八方向bfs
#include <iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=10;
typedef pair<int,int>PII;
PII start,en;
int dist[maxn][maxn];
int dx[]={-2,-1,-2,-1,1,2,2,1};
int dy[]={-1,-2,1,2,-2,-1,1,2};
int bfs()
{
memset(dist,-1,sizeof(dist));
dist[start.first][start.second]=0;
queue<PII> pq;
while(!pq.empty()) pq.pop();
pq.push(start);
while(!pq.empty())
{
PII k=pq.front();
pq.pop();
if(k.first==en.first&&k.second==en.second) return dist[k.first][k.second];
for(int i=0;i<8;i++)
{
int nx=k.first+dx[i],ny=k.second+dy[i];
if(nx>=1&&nx<9&&ny>=0&&ny<8&&dist[nx][ny]==-1) {
dist[nx][ny]=dist[k.first][k.second]+1;
pq.push(PII(nx,ny));
}
}
}
}
int main()
{
char a[5],b[5];
while(scanf("%s%s",a,b)==2)
{
start.first=a[1]-'0'; //行数
start.second=a[0]-'a'; //列数
en.first=b[1]-'0';
en.second=b[0]-'a';
printf("To get from %s to %s takes %d knight moves.\n",a,b,bfs());
}
return 0;
}
双向bfs:
//双向bfs
//双向bfs是指使用两个队列,一个队列保存从起点开始的状态,另一个队列保存从终点开始向前搜索的状态
//其主要需要注意的是每个状态是由起点搜索到的还是由终点搜索到的,这样当两种状态相交时把步数相加即为结果
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int>PII;
const int maxn=10;
int dx[]={-2,-1,-2,-1,1,2,2,1};
int dy[]={-1,-2,1,2,-2,-1,1,2};
PII start,en;
int dist[maxn][maxn];
int color[maxn][maxn];
int bfs()
{
queue<PII>p1; //从起点开始搜索
while(!p1.empty()) p1.pop();
queue<PII>p2; //从终点开始搜索
while(!p2.empty()) p2.pop();
memset(dist,-1,sizeof(dist));
memset(color,-1,sizeof(color));
p1.push(start);
p2.push(en);
dist[start.first][start.second]=dist[en.first][en.second]=0;
color[start.first][start.second]=1;
color[en.first][en.second]=2;
while(!p1.empty()||!p2.empty())
{
if(!p1.empty()) {
PII k=p1.front();
p1.pop();
for(int i=0;i<8;i++)
{
int nx=k.first+dx[i],ny=k.second+dy[i];
if(nx>=1&&nx<9&&ny>=0&&ny<8) {
if(color[nx][ny]==-1) {
color[nx][ny]=1;
dist[nx][ny]=dist[k.first][k.second]+1;
p1.push(PII(nx,ny));
}
else if(color[nx][ny]==2) return dist[nx][ny]+dist[k.first][k.second]+1;
}
}
}
if(!p2.empty()) {
PII k1=p2.front();
p2.pop();
for(int i=0;i<8;i++)
{
int nx=k1.first+dx[i],ny=k1.second+dy[i];
if(nx>=1&&nx<9&&ny>=0&&ny<8) {
if(color[nx][ny]==-1) {
color[nx][ny]=2;
dist[nx][ny]=dist[k1.first][k1.second]+1;
p2.push(PII(nx,ny));
}
else if(color[nx][ny]==1) return dist[nx][ny]+dist[k1.first][k1.second]+1;
}
}
}
}
}
int main()
{
char a[5],b[5];
while(scanf("%s%s",a,b)==2)
{
start.first=a[1]-'0'; //行数
start.second=a[0]-'a'; //列数
en.first=b[1]-'0';
en.second=b[0]-'a';
if(start.first==en.first&&start.second==en.second) printf("To get from %s to %s takes 0 knight moves.\n",a,b);
else printf("To get from %s to %s takes %d knight moves.\n",a,b,bfs());
}
return 0;
}