<wbr>中国象棋中的跳马问题</wbr>
题目描述
现在棋盘的大小不一定,由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 13
样例输出
1 can not reach!
提示
<wbr></wbr>
此题是一个搜索题,可用DFS或BFS,建议选择BFS(广搜)。一开始把马的起始点加入队列,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组用来记录此点在之前是否已经加入队列,如果加入过队列当中,就不需要再加入了,直到队列里的元素为空,或者搜索到了终点,搜索即停止,然后输出相应答案即可。
参考代码如下:
#include<stdio.h>
#define MAX 150
#define SIZE 10201
#define OK 1
//马下一步最多能跳的地方的个数
#define M 8
//马可能跳的位置的相对横纵坐标,上、右、下、左
int Movex[M] = {-1,1, 2, 2, 1,-1, -2,-2};
int Movey[M] = { 2,2, 1,-1, -2,-2, -1,1};
//马跳的时候最多遇到的障碍数
#define B 4
//马的障碍的位置的相对总横坐标,上、右、下、左
int Barx[B] = {0,1,0,-1};
int Bary[B] = {1,0,-1,0};
typedef struct
{
int step;//记录步数
int flag;//标记
}Chessboard;//棋盘类型
typedef struct
{
int lnum;
int rnum;//记录元素下标
}Queue;//队列类型
Queue queue[SIZE];//队列
int rear,front;//队列指针
Chessboard board[MAX][MAX];
int a,b,c,d,row,line;//起点,终点坐标以及行列值
int BFS()
{
int x0,y0;
int mx,my,bx,by;
int i;
rear=-1;
front=-1;//队列指针初始化
board[a][b].step=0;//起点的步数记为0
board[a][b].flag=1;//起点标记已经进过队列
rear++;
queue[rear].lnum=a;
queue[rear].rnum=b;//起点先进队列
while(front!=rear)//队列不为空
{
front++;
x0=queue[front].lnum;
y0=queue[front].rnum;//出队列
if(x0==c && y0==d) return OK;//找到了终点就停止搜索
for(i=0;i<M;i++)//m=8,共有八个地方可以跳
{
//算出值,利用该值来判断向该方向跳是否有障碍物阻碍
bx = x0+Barx[i/2];
by = y0+Bary[i/2];//用来判断是否有障碍物
//算出值,利用该值来判断向该方向上日字的端点处是否有障碍物或已走过
//即下一位置的坐标
mx = x0 + Movex[i];
my = y0 + Movey[i];
if(board[bx][by].flag!=-1)
{
if(mx>0&&mx<=row && my>0&&my<=line && !board[mx][my].flag)//不能越界,board[mx][my].flag必为0
{
rear++;
queue[rear].lnum=mx;
queue[rear].rnum=my;//进队列
board[mx][my].flag=1;//标记为已经走过
board[mx][my].step=board[x0][y0].step+1;//路径值是其根部的路径值加1
}//if
}//if
}//for
}//while
return 0;
}
int main()
{
int n,m,e,f;
int k,i,j;
scanf("%d",&n);//一共n组测试数据
for(k=0;k<n;k++)
{
scanf("%d %d",&row,&line);//输入棋盘大小 行列
for(i=1;i<=row;i++)
for(j=1;j<=line;j++)
board[i][j].flag=0;//初始化,全部标记为0
scanf("%d %d %d %d",&a,&b,&c,&d);//输入起点终点坐标值
scanf("%d",&m);//m个障碍
for(i=0;i<m;i++)
{
scanf("%d %d",&e,&f);
board[e][f].flag=-1;//障碍点标记为-1
}
if(BFS())
printf("%d\n",board[c][d].step);
else printf("can not reach!\n");
}
return 0;
}
分享到:
相关推荐
c语言课程设计 跳马 中国象棋程序完全可以运行 而且算法简单易懂
国际象棋跳马问题,在n*n棋盘上,让马遍历左右方格。界面文件。
设计一个国际象棋的跳马演示程序, 基本要求:将马随机放进8*8的棋盘内,按马的行走规则,每个方格进入一次. 走遍64个方格,将数字依次填入8*8个方格内,并输出. 较高要求:1.求出从某一起点出发的多条以致全部...
用回溯法求解跳马问题
关于跳马的c语言课程设计报告 内附原代码
参考使用,欢迎下载
pascal 跳马问题:在5*5格的棋盘上,从1点出发,按日字跳马,要求不重复地跳经所有方格.求出符合要求的所有跳马方案,输出前5个方案及总方案数.
哈夫曼码的编译码系统;递归替换问题;跳马问题;长整数运算问题;数据结构课程设计课程设计.pdf
跳马问题。要求在64个国际象棋格子,任意位置放一个马,如何不重复地把格子走完。
c/c++语言解决跳马问题,广度优先搜索,算法设计与分析
现在棋盘的大小不一定,由p,q给出,并且在棋盘中将出现障碍物(限制马的行动,与象棋走法相同) 输入 第一行输入n表示有n组测试数据。 每组测试数据第一行输入2个整数p,q,表示棋盘的大小(1,q)。 每组测试数据第...
问题描述与实验目的 给定8*8方格棋盘,求棋盘上一只马从一个位置到达另一位置的最短路径长。 注意马是走“日”形的。
参考别人写的一个,在win-tc上运行通过,完成跳马的遍历
跳马算法,有一m*n的棋盘,一马放在棋盘中任意位置,马按中国象棋跳法,从初始位置起跳,跳至边界后返回,求所有能返回初始位置的周游路线
问题描述 给定8*8方格棋盘,求棋盘上一只马从一个位置到达另一位置的最短路径长。 注意马是走“日”形的。 输入 输入有若干测试数据。 每组测试数据仅1行,每行上有2个方格pos1、pos2,之间用一个空格隔开,每...
编写一个小程序,让用户解决跳马问题,要求在图形界面下,给出一个5行9列的棋盘,要求找到马从左下角位置走到右上角的正确路径,只能往右走。 过30分钟以后,用户还找不到正确路径,使用回溯法,程序搜索解空间树给...
算法与数据结构课程设计源码与文档,题目为跳马问题、校园导游咨询
数据结构课程设计,本科生必备材料,请各位自己参考
跳马问题的C#代码,经过实践的检验,可以运行。
给出一个n*n的棋盘,一个放在棋盘某个位置上的马是否可以恰好访问每个方格一次,并回到其实位置上?运用回溯算法和贪心算法实现。效率高。