1 /* 2 转自http://blog.csdn.net/custqi/article/details/6455425 3 感觉对双向广搜写得挺清楚的 4 */ 5 #include<iostream> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int maxn = 301; 10 int n; 11 int used[maxn][maxn]; 12 int g[maxn][maxn]; 13 int d[8][2] = { { -2, -1 }, { -2, 1 }, { -1, -2 }, { -1, 2 }, { 1, -2 }, { 1, 2 }, { 2, -1 }, { 2, 1 } }; 14 15 struct Point 16 { 17 int x, y; 18 }st, ed; 19 int Check(int x, int y) 20 { 21 return (x >= 0 && x<n && y >= 0 && y<n); 22 } 23 int solve() 24 { 25 int sx, sy, tx, ty; //sx,sy 先前结点 tx,ty生成新结点 26 queue<Point>Q; 27 Point curNode, nextNode; 28 memset(used, 0, sizeof(used)); 29 //放入起始结点 30 g[st.x][st.y] = 0; 31 used[st.x][st.y] = 1;//由起始结点方向扩展的结点记录值为 1 32 Q.push(st); 33 //放入终止结点 34 g[ed.x][ed.y] = 0; 35 used[ed.x][ed.y] = 2;//由终止结点方向扩展的结点记录值为 2 36 Q.push(ed); 37 //同时放入起始结点和终止结点 进行双向广搜 38 while (!Q.empty()) 39 { 40 curNode = Q.front(); 41 Q.pop(); 42 sx = curNode.x; 43 sy = curNode.y; 44 for (int i = 0; i<8; i++) 45 { 46 tx = sx + d[i][0]; 47 ty = sy + d[i][1]; 48 if (!Check(tx, ty)) continue; 49 if (used[tx][ty] == 0) //如果used[tx][ty]未访问过 50 { 51 g[tx][ty] = g[sx][sy] + 1; //更新在tx ty的值 52 nextNode.x = tx; 53 nextNode.y = ty; 54 used[tx][ty] = used[sx][sy]; // 55 Q.push(nextNode); 56 } 57 else if (used[sx][sy] != used[tx][ty]) //起始方向与终止方向同时进行后,此时的结点为俩个方向相遇的点,得到结果 58 { 59 return g[sx][sy] + g[tx][ty] + 1; 60 } 61 } 62 } 63 return 0; 64 } 65 int main() 66 { 67 int TestCases; 68 scanf("%d", &TestCases); 69 while (TestCases--) 70 { 71 scanf("%d%d%d%d%d", &n, &st.x, &st.y, &ed.x, &ed.y); 72 printf("%d/n", solve()); 73 } 74 return 0; 75 }