有个汉子,和一匹马,从5*5的棋盘一角出发,要走完棋盘的每一个角落,对没错,每一个角落。输出所有的走法。如:
输出格式示例:
1 16 21 10 25
20 11 24 15 22
17 2 19 6 9
12 7 4 23 14
3 18 13 8 5
示例中的数字代表的是所走的步数。
首先,我们知道马在棋盘上正常情况下共有八个可走的方向,这八个方向会在回溯算法中多次调用,所以我们可以用两个数组来储存它们。然后就是进行遍历,判断按照该方向下一步是否会越界,若不会越界,则 判断该方向下一步是否已经走过,若走过(标志变量被修改为了所走的步数),则换一个方向,若没走过(标志变量为0),则将该位置标记。然后重复该过程,若遍历了所有的方向,不用小子说大家也懂,那就回溯一步。
来看看代码:
1 #include<stdio.h> 2 int sum=0; 3 int board[5][5]={0}; 4 int x[8]={1,2,2,1,-1,-2,-2,-1};//储存八个方向 5 int y[8]={2,1,-1,-2,2,1,-1,-2};//储存八个方向 6 void out();//输出函数 7 void f(int k,int a,int b);//k统计步数,a为上一位置的横坐标,b为上一位置的纵坐标 8 int main() 9 { 10 board[0][0]=1; 11 f(2,0,0); 12 return 0; 13 } 14 void f(int k,int a,int b) 15 { 16 int i; 17 for(i=0;i<=7;i++) 18 { 19 if( (a+x[i]>=0) && (a+x[i]<=4) //判断该方向下一步的横坐标是否越界 20 && (b+y[i]>=0) && (b+y[i]<=4) /*判断该方向下一步的纵坐标是否越界*/) 21 { 22 if(board[a+x[i]][b+y[i]]==0) 23 { 24 board[a+x[i]][b+y[i]]=k; 25 if(k==25) 26 out(); 27 else 28 f(k+1,a+x[i],b+y[i]); 29 board[a+x[i]][b+y[i]]=0; 30 } 31 } 32 } 33 } 34 void out() 35 { 36 int i,j; 37 sum++; 38 printf("第%d种走法:\n",sum); 39 for(j=0;j<=4;j++) 40 { 41 for(i=0;i<=4;i++) 42 { 43 printf("%d\t",board[i][j]); 44 } 45 printf("\n"); 46 } 47 } 48 //注意,若按照该代码进行,将不能达成题目的输出所有解的要求,若想达成此要求,则需要同学自行使用重定向(freopen)输出
代码如有不足之处,欢迎指出!
时间: 2024-08-04 20:17:56