中国象棋中的跳马问题

题目描述

现在棋盘的大小不一定,由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(广搜)。一开始把马的起始点加入队列,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组用来记录此点在之前是否已经加入队列,如果加入过队列当中,就不需要再加入了,直到队列里的元素为空,或者搜索到了终点,搜索即停止,然后输出相应答案即可。


这个题目本人主要用的是BFS的方法 把象棋的位置 以及从初始点到该点走的步数弄成一个结构体 然后再使用STL中的队列容器 在oprate函数中 主要分为三个部分 第一个是对首元素入队列 然后就是对头取元素 再扩展。                                                                                      这里声明一点在main函数注意边界问题  再过一段时间我再写双向BFS 以及DFS代码
#include <iostream>
#include <algorithm>
#include <queue>
#include <stdio.h>
using namespace std;
int oprate(int a[]);
int in(int ,int);
typedef struct chess
{
    int x;
    int y;
    int mun;
}chess;
queue<chess>Q;
int b[105][105]= {0};
int L[16]={-2,1,-2,-1,-1,-2,1,-2,2,-1,2,1,1,2,-1,2};
int I[16]={-1,0,-1,0,0,-1,0,-1,1,0,1,0,0,1,0,1};
int xx;int yy;
int main()
{
    int a[5];
    int n,m,k,z,sum;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d %d",&xx,&yy);
        for(int i=0; i<4; i++)
            scanf("%d",&a[i]);
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d %d",&k,&z);
            b[k][z]=2;
        }
        sum=oprate(a);
        if(sum==-1)
            printf("can not reach!\n");
        else
            printf("%d\n",sum);
        for(int i=0;i<=xx;i++)
            for(int j=0;j<=yy;j++)
             b[i][j]=0;
    }
    return 0;
}
int  oprate ( int  a[ ] )
{
   chess  d;chess  g;
   d.x=a[0];d.y=a[1];d.mun=0;
   b[d.x][d.y]=1;
   Q.push(d);
   while(!Q.empty())
   {
       d=Q.front();Q.pop();
       if(d.x==a[2]&&d.y==a[3])
        {
            while(!Q.empty())
                Q.pop();
            return d.mun;
        }
       for(int i=0;i<8;i++)
       {
          if(in(d.x+L[2*i],d.y+L[2*i+1])&&b[d.x+L[2*i]][d.y+L[2*i+1]]==0)
          {
              if(b[d.x+I[2*i]][d.y+I[2*i+1]]==2)
                continue;
              else
                 {
                     b[d.x+L[2*i]][d.y+L[2*i+1]]=1;
                     g.x=d.x+L[2*i];
                     g.y=d.y+L[2*i+1];
                     g.mun=d.mun+1;
                     Q.push(g);
                 }
          }
       }
   }
   return -1;
}
int in(int x,int y)
{
    if(x<=xx&&x>0&&y>0&&y<=yy)
        return 1;
    else
        return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值