e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6Sample Output
To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.
(1)求任意两点间的最短步数
该问题不需要求出该两点间的路径上的点,也不需要求出拥有该最短步数的路径个数,只需将其间的最短步数求出即可;
(2)求任意两点间的所有最短路径及其全部信息
路径信息:路径上的每一点
该问题不仅需要求出两点间的最短路径,且要求出这样的最短路径有多少条和每一条路径上的每一点
(3)骑士周游世界问题
在一个8×8的方格棋盘中,按照国际象棋中马的行走规则从棋盘上的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格,这样的一条周游路线在数学上被称为国际象棋盘上汉密尔顿链,求从任意一点出发,所有这样的汉密尔顿链及其全部信息;
(1)棋盘的表示方法
可以用一个9×9的二维数组chess[9][9]来表示国际象棋的棋盘,在马还没有开始行走时,棋盘上所有的格都置为零,以后,马跳到哪个格,就将马跳跃的步数加1后的值记录在相应的空格里;开始点在行走前设为1;
注:为表示方便,取9×9,数组均下标从1开始;
(2)马的跳跃方向
在国际象棋的棋盘上,一匹马共有8个可能的跳跃方向,如图1所示,按顺时针分别记为1~8,设置一组坐标增量来描述这8个方向;
一开始题意愣是没理解,还以为一格格走,不知道要马走日.多亏下面真~大佬的思路,也很喜欢他写的,因为没有代码.
https://blog.csdn.net/livelylittlefish/article/details/2108045
代码:
#include//knight moves
#include
#include
#define M 10
using namespace std;
int ma[M][M];
int ne[8][2]= {{1,-2},{2,-1},{2,1},{1,2},//马走日的八个方向.
{-1,2},{-2,1},{-2,-1},{-1,-2}
};
struct node
{
int x;
int y;
int step;
};
int main()
{
int ex,ey;
char st[3],ed[3];
while(~scanf("%s%s",st,ed))
{
memset(ma,0,sizeof(ma));
ex=ed[0]-'a';//转化终点.并记录
ey=ed[1]-'1';
struct node n;//转化起点,并且准备入队首.
n.x=st[0]-'a';
n.y=st[1]-'1';
n.step=0;//记得初始化起点的步数.
ma[n.x][n.y]=0;//这个也是
queue q;
q.push(n);
// for(int i=0;i<8;i++)//搜索前的棋盘步数格局(检验bug的时候看)
// {
// for(int j=0;j<8;j++)
// printf("%d ",ma[i][j]);
// printf("\n");
// }
while(!q.empty())
{
// printf("1\n");//看看有没有死循环,在修bug 的时候
node n=q.front();
q.pop();
if(n.x==ex&&n.y==ey)//如果走到了终点
{
printf("To get from %s to %s takes %d knight moves.\n",st,ed,n.step);
break;//记得跳出循环,记得跳出循环,记得跳出循环
}
for(int i=0; i<8; i++)
{
struct node nn;
nn.x=n.x+ne[i][0];
nn.y=n.y+ne[i][1];
if(nn.x<0||nn.x>=8||nn.y<0||nn.y>=8||ma[nn.x][nn.y]!=0)//如果这个点不在棋盘里或者这个点已经被走过
continue;
else//如果满足在棋盘,并且没走过
{
nn.step=n.step+1;//每次扩展一次方向,则增加一步.
ma[nn.x][nn.y]=nn.step;//标记步数在棋盘里.(这步其实只要标记一下就好了,这为了方便看他是怎么走的 步数的动态)
q.push(nn);//入队列.
}
}
}
// for(int i=0;i<8;i++)//队列搜索完后的棋盘步数格局(检验bug的时候看)
// {
// for(int j=0;j<8;j++)
// printf("%d ",ma[i][j]);
// printf("\n");
// }
while(!q.empty())//清空队列;
q.pop();
}
return 0;//这是个好习惯
}
ps:2018-04-16 21:23:14
终于终于 大部分凭自己把bfs做出来了 超级开心???(滑稽脸)菜鸡自娱自乐.
个人赛选拔结束了,自己打的很菜.但是多谢大佬带我,真的很感激,如果不能请到集训的假,我应该坚持不下来吧.
很感谢你.我会努力刷专题,补题多看英语,追上你们的步伐的.