题目:
http://poj.org/problem?id=2243
题意:
给定一个 8∗8 的棋盘,编号为 1−8和a−h ,按照给定的走法, 求从起点到终点需要的最少步数
思路:
直接
bfs
或者
双向bfs
都可以,在这题中,
双向bfs
终于展现了比
bfs
高的多的效率
bfs:
//700ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int N = 500 + 10, INF = 0x3f3f3f3f;
int n;
int dis[N][N];
int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2}, dy[] = {-1, 1, -2, 2, -2, 2, -1, 1};
int bfs(int sx, int sy, int tx, int ty)
{
queue<pii> que;
memset(dis, 0x3f, sizeof dis);
que.push(pii(sx, sy)), dis[sx][sy] = 0;
while(! que.empty())
{
pii p = que.front(); que.pop();
if(p.first == tx && p.second == ty) return dis[tx][ty];
for(int i = 0; i < 8; i++)
{
int nx = p.first + dx[i], ny = p.second + dy[i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= n && dis[nx][ny] > dis[p.first][p.second] + 1)
{
dis[nx][ny] = dis[p.first][p.second] + 1;
que.push(pii(nx, ny));
}
}
}
return -1;
}
int main()
{
int t, sx, sy, tx, ty;
char ch1, ch2;
n = 8;
while(~ scanf(" %c%d %c%d", &ch1, &sy, &ch2, &ty))
{
sx = ch1 - 'a' + 1, tx = ch2 - 'a' + 1;
printf("To get from %c%d to %c%d takes %d knight moves.\n", ch1, sy, ch2, ty, bfs(sx, sy, tx, ty));
}
return 0;
}
双向bfs:
//100ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int N = 10 + 10, INF = 0x3f3f3f3f;
int n;
int dis[N][N], vis[N][N];
int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2}, dy[] = {-1, 1, -2, 2, -2, 2, -1, 1};
int bfs(int sx, int sy, int tx, int ty)
{
queue<pii> que;
memset(dis, 0, sizeof dis);
memset(vis, 0, sizeof vis);
if(sx == tx && sy == ty) return 0;
que.push(pii(sx, sy)), dis[sx][sy] = 0, vis[sx][sy] = 1;
que.push(pii(tx, ty)), dis[tx][ty] = 0 ,vis[tx][ty] = 2;
while(! que.empty())
{
pii p = que.front(); que.pop();
for(int i = 0; i < 8; i++)
{
int nx = p.first + dx[i], ny = p.second + dy[i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= n)
{
if(! vis[nx][ny])
{
vis[nx][ny] = vis[p.first][p.second];
dis[nx][ny] = dis[p.first][p.second] + 1;
que.push(pii(nx, ny));
}
else if(vis[p.first][p.second] != vis[nx][ny])
return dis[p.first][p.second] + dis[nx][ny] + 1;
}
}
}
return 0;
}
int main()
{
int t, sx, sy, tx, ty;
char ch1, ch2;
n = 8;
while(~ scanf(" %c%d %c%d", &ch1, &sy, &ch2, &ty))
{
sx = ch1 - 'a' + 1, tx = ch2 - 'a' + 1;
printf("To get from %c%d to %c%d takes %d knight moves.\n", ch1, sy, ch2, ty, bfs(sx, sy, tx, ty));
}
return 0;
}