题目:
原题链接:POJ-1915
题目大意:
输入一个数t表示测试样例有t个
每个测试样例有三行,第一行n代表棋盘大小为n*n,第二行表示起点的坐标,第三行表示终点坐标
每一步都按照国际象棋骑士的走法走,求最少的步数中起点走到终点
代码:
#include <cstdio>
#include<cstring>
#include<queue>
using namespace std;
bool vis[305][305];//标记是否走过
int dir[8][2]= {1,2,-1,2,-2,1,-2,-1,-1,-2,1,-2,2,-1,2,1}; //记录八个方向
int x1,x2,y1,y2;
int l;
struct point
{
int x;
int y;
int step;
};
void bfs()
{
queue<point> piece;//宽度优先算法需要借助队列
point start;//起始点定义
start.x=x1;
start.y=y1;
start.step=0;
piece.push(start);//起始点如队
while(!piece.empty())
{
point now,next;
now=piece.front();
piece.pop();
if(now.x==x2&&now.y==y2)//当到达终点时输出步数并跳出函数
{
printf("%d\n",now.step);
return;
}
for(int i=0; i<8; i++)//尝试八个方向
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
if(next.x>=0&&next.x<l&&next.y>=0&&next.y<l&&!vis[next.x][next.y])//在边界内且未被标记
{
vis[next.x][next.y]=true;//标记下一步位置
next.step=now.step+1;//步数加一
piece.push(next);//入队
}
}
}
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&l);
scanf("%d %d",&x1,&y1);//起始点
scanf("%d %d",&x2,&y2);//终点
memset(vis,false,sizeof(vis));//初始化标记
vis[x1][y1]=true;//标记起点
bfs();
}
return 0;
}