#include<iostream> #include<cmath> #include<queue> using namespace std; const int maxn = 301; int n; int used[maxn][maxn]; int g[maxn][maxn]; int d[8][2] = { {-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1} }; //int x[] = {-2,-2,-1,-1,1,1,2,2}; //int y[] = {-1,1,-2,2,-2,2,-1,1}; struct Point { int x,y; }st,ed; int Check(int x,int y) { return (x>=0 && x<n && y>=0 &&y<n); } int solve() { int sx,sy,tx,ty; //sx,sy 先前结点 tx,ty生成新结点 queue<Point>Q; Point curNode,nextNode; memset(used,0,sizeof(used)); //放入起始结点 g[st.x][st.y] = 0; used[st.x][st.y] = 1;//由起始结点方向扩展的结点记录值为 1 Q.push(st); //放入终止结点 g[ed.x][ed.y] = 0; used[ed.x][ed.y] = 2;//由终止结点方向扩展的结点记录值为 2 Q.push(ed); //同时放入起始结点和终止结点 进行双向广搜 while(!Q.empty()) { curNode = Q.front(); Q.pop(); sx = curNode.x; sy = curNode.y; for(int i=0;i<8;i++) { tx = sx + d[i][0]; ty = sy + d[i][1]; if(!Check(tx,ty)) continue; if(used[tx][ty]==0) //如果used[tx][ty]未访问过 { g[tx][ty] = g[sx][sy]+1; //更新在tx ty的值 nextNode.x = tx; nextNode.y = ty; used[tx][ty] = used[sx][sy]; // Q.push(nextNode); } else if(used[sx][sy]!=used[tx][ty]) //起始方向与终止方向同时进行后,此时的结点为俩个方向相遇的点,得到结果 { return g[sx][sy] + g[tx][ty] + 1; } } } return 0; } int main() { int TestCases; scanf("%d",&TestCases); while(TestCases--) { scanf("%d%d%d%d%d",&n,&st.x,&st.y,&ed.x,&ed.y); printf("%d/n",solve()); } return 0; }