http://poj.org/problem?id=1915
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
typedef struct point{
int x, y;
int moves;
}point;
queue<point> Q[2];
bool mp[2][305][305];
int mov[2][305][305];
int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};
int n;
int dbfs(point s,point e)
{
//起点终点相同
if(s.x == e.x && s.y == e.y)
return 0;
int inx = 0;
mp[0][s.x][s.y] = 1;
mp[1][e.x][e.y] = 1;
point head, t, tail;
Q[0].push(s);
Q[1].push(e);
while(!Q[0].empty() || !Q[1].empty())
{
inx = (inx ^ 1); //改变搜索队列
int siz = Q[inx].size();
//单队列bfs
for(int j = 0;j < siz;j ++)
{
head = Q[inx].front();
Q[inx].pop();
//另一个队列访问过此点了 则说明相遇
if(mp[inx^1][head.x][head.y])
return mov[0][head.x][head.y] + mov[1][head.x][head.y];
for(int i = 0;i < 8;i ++)
{
int dx = head.x + dir[i][0];
int dy = head.y + dir[i][1];
if(dx < 0 || dy < 0 || dx >= n || dy >= n || mp[inx][dx][dy]) continue;
t.x = dx;
t.y = dy;
t.moves = head.moves + 1;
mp[inx][dx][dy] = true;
mov[inx][dx][dy] = head.moves + 1;
Q[inx].push(t);
}
}
}
return 0;
}
int main()
{
int t;
point s, e;
cin >> t;
while(t --)
{
scanf("%d",&n);
scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
memset(mp,0,sizeof(mp));
memset(mov,0,sizeof(mov));
while(!Q[0].empty())
Q[0].pop();
while(!Q[1].empty())
Q[1].pop();
s.moves = 0;
e.moves = 0;
cout << dbfs(s,e) << '\n';
}
return 0;
}