题目:

POJ-1915(Knight Moves)(BFS)
原题链接: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;
}

相关文章: