中国象棋中的跳马问题(bfs)

题目描述

现在棋盘的大小不一定,由p,q给出,并且在棋盘中将出现障碍物(限制马的行动,与象棋走法相同)

输入

第一行输入n表示有n组测试数据。

每组测试数据第一行输入2个整数p,q,表示棋盘的大小(1<=p,q<=100)。
每组测试数据第二行输入4个整数,表示马的起点位置与终点位置。(位置的取值范围同p,q)
第三行输入m表示图中有多少障碍。
接着跟着m行,表示障碍的坐标。

输出

马从起点走到终点所需的最小步数。
如果马走不到终点,则输入“can not reach!”

样例输入

2
9 10
1 1 2 3
0
9 10
1 1 2 3
8
1 2
2 2
3 3
3 4
1 4
3 2
2 4
1 3

样例输出

1
can not reach!

提示

此题是一个搜索题,可用DFS或BFS,建议选择BFS(广搜)。一开始把马的起始点加入队列,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组用来记录此点在之前是否已经加入队列,如果加入过队列当中,就不需要再加入了,直到队列里的元素为空,或者搜索到了终点,搜索即停止,然后输出相应答案即可。

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
int num[6];

bool visti[101][101];
struct postion2
{
    int x;
    int y;
    int sum;
};
struct postion1
{
    int x;
    int y;
};
postion1 dir[8]= {{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2},{-1,2}};
//postion1 dir2[8]= {{-1,0},{-1,0},{0,-1},{0,-1},{1,0},{1,0},{0,1},{0,1}};
postion1 dir2[8]= {{-1,0},{0,-1},{1,0},{0,1}};   //象棋中马的走法有限制
queue<postion2> que;
int zhangai[101][101];
int ans=0,m;
int p,q;            //棋盘大小
bool check(int a,int b)
{
    if(a<=p && a>0 && b<=q && b>0)
        return true;
    return false;
}
int bfs()
{
    postion2 be,da,he;
    be.x=num[0];
    be.y=num[1];
    be.sum=0;
    que.push(be);
    visti[num[0]][num[1]]=true;
    while(!que.empty())
    {
        da=que.front();
        que.pop();
        if(da.y==num[3] && da.x==num[2])
            return da.sum;
        for(int i=0; i<8; i++)
        {
            if(check(da.x+dir[i].x,da.y+dir[i].y) && !visti[da.x+dir[i].x][da.y+dir[i].y] && !zhangai[da.x+dir[i].x][da.y+dir[i].y] && zhangai[da.x+dir2[i/2].x][da.y+dir2[i/2].y]==0)
            {
                he.x=da.x+dir[i].x;
                he.y=da.y+dir[i].y;
                he.sum=da.sum+1;
                que.push(he);
                visti[da.x+dir[i].x][da.y+dir[i].y]=true;

            }
        }
    }
    return -1;
}

int main()
{
    int n,i;
    scanf("%d",&n);   // n组数据
    while(n--)
    {
        memset(zhangai,0,sizeof(zhangai));
        memset(visti,false,sizeof(visti));
        while(!que.empty())  que.pop();
        int x,y;
        scanf("%d %d",&p,&q);
        scanf("%d %d %d %d",&num[0],&num[1],&num[2],&num[3]);
        scanf("%d",&m);
        for(i=1; i<=m; i++)
        {
            scanf("%d%d",&x,&y);
            zhangai[x][y]=1;
            visti[x][y]=true;
        }
        ans=bfs();
        if (ans!=-1)
            printf("%d\n",ans);
        else
            printf("can not reach!\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值