马踏棋盘
- 问题描述:
将马放到国际象棋的88棋盘上的任意指定方格中,
按照马的走棋规则将“马”进行移动,
要求每个方格进入且只进入一次,走遍棋盘上的64个方格,
将数字1,2,3…,64依次填入一个88的方阵。
- 递归
首先我在这里用了一个10*10的表格而不是8*8的表格。
为什么这样用呢?我主要考虑到了边界问题,马一共有8中踏出方式,
可是到了边界时马的踏出方式就变得很复杂要考虑踏出问题。所以我就用了10*10的
在出边界时,只要判断一下就可以了。
这里有一个问题,我想说下,马是否踏到第64步?如果马踏到第64步时,输出,抹步数,返回第63步时,63步又进行踏出,循环判断,又会回到刚刚踏到的第64步,如此循环,就会有问题。
解决方案:其实就是你在判断是否能踏得时候,能踏得话,先count++。假入在第63步时,进入horse循环,此时R(行)和C(列)是即将要踏得第64步,能放进入,直接count++,满64输出。简而言之,就是64不踏,在63步时进行判断,输出。
#include <stdio.h>
#include<stdlib.h>
// 棋盘
int chess[12][12];
//统计马一共有多少步
int num;
//马走的方向
int move[8][2]={{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}};
//统计马一共有多少步
int count;
//输出函数
void print()
{
int i,j;
printf("num= %d\n",num);
/*
if(num>20)
exit(0);
*/
for(i=2;i<10;i++)
{
for(j=2;j<10;j++)
printf("%d ",chess[i][j]);
printf("\n");
}
printf("**************************\n");
}
//马走的方式
void horse(int x,int y)
{
int i,j;
for(i=0;i<8;i++) //在8*8的矩阵里走
{
int R=x+move[i][0]; //马的下一步的行值
int C=y+move[i][1];// 马的下一步的列值
if(!chess[R][C] ) //能放 该位置为0且不出界
{
count++;
if(count<64)//当马踏的步数小于64时,进入下一步
{
chess[R][C]=count; //第几步
horse(R,C);//进入下一层
//回溯回来时,说明上一次马的步数有问题,抹步数
count--;
chess[R][C]=0;
}
else{
//当马踏满64步时,输出
num++;
print();
//抹步数
count--;
chess[R][C]=0;
}
}
}
}
int main(void)
{
int i,j;
//初始化
for(i=0;i<12;i++)
{
for(j=0;j<12;j++)
{
if(i<2 || i>9)
chess[i][j]=-1;
else if(j<2 || j>9)
chess[i][j]=-1;
}
}
//马的初始位置
chess[2][2]=++count;
horse(2,2);
//踏的全部方式
/* for(i=2; i<10; i++){
for(j=2; j<10; j++){
// 先把马放在初始位置
count = 0;
chess[i][j] =++count;
horse(i,j);
}
}
*/
}