关于马的走法,很让我抑郁,高手们帮帮我
在一个4*5的棋盘上,输入马的起始位置坐标(纵、横),求马能返回初始位置的所有不同走法的总数(马走过的位置不能重复,马走“日”字)。这是我在论坛上看到的一个程序,我对每个语句都理解,也清楚是什么意思,可就是逻辑上有些糊涂,他到底怎么实现功能的,而且我也觉得这个程序好像有些错误,这是我自己的一些注释;希望大家可以帮下我弄清楚这个流程是怎么回事也就是从算法的角度帮我讲解下 谢谢程序代码:
#include<stdio.h> #include<string.h> //头文件 int dir[8][2]={{2,1},{1,2},{-1,2},{-2,1},{1,-2},{2,-1},{-1,-2},{-2,-1}}; //定义一个二维数组,代表马走的几种情况,因为马是进二平一的走日字型,这里面囊括了马走前后左右的全部情况 int count; //定义一个count,用来计马能返回初始位置的所有不同走法的总数 int n,m; //n,m为马的起始位置的坐标 int map[6][7]; //定义map数组用来规定马走过的位置不能重复,具体用到时再说 void bfs(int x,int y) //定义一个函数,在其中实现主要功能 { int xx,yy; //xx,yy是用来记录马每走一步后的坐标 int i; //定义整型i,for语句要用到 for(i=0;i<8;i++) //for语句循环 { xx=x+dir[i][0]; yy=y+dir[i][1]; //这两句其实就是让马行进一步后的结果,xx,yy就是行进后马的坐标 if(xx>5||xx<=0||yy>4||yy<=0) continue; //这两句是判断语句,如果满足if语句中的任何一个条件,表示坐标越界,结束本次循环,返回for语句进行下一次循环。否则顺序执行 if(map[xx][yy]) continue; //如果map[xx][yy]为1,代表马已经走过此步,不能再走此步,结束本次循环,返回for语句进行下一次循环。否则顺序执行 if(xx==n&&yy==m) { count++; continue; } //如果xx=n并且yy=m表示马已经返回原始位置,完成一次返回原始位置的走法,count加1,结束本次循环,返回for语句进行下一次循环。否则顺序执行 map[xx][yy]=1; //给map[xx][yy]赋一,代表已近走过此步 bfs(xx,yy); //再次调用此函数,将xx,yy作为初始值x,y继续执行,直到返回原位置 map[xx][yy]=0; } } int main() //主函数,程序开始的位置 { while(scanf("%d%d",&n,&m)!=EOF) //循环语句,输入起始坐标,EOF为结束标志 { count=0; //count赋初值 memset(map,0,sizeof(map)); //清零map数组的所有项 bfs(n,m); //调用bfs函数进行求马能返回初始位置的所有不同走法的总数 printf("%d\n",count); //输出count值 } return 0; //如果程序无语法错误,主函数的返回值为0 }