馬踏棋盤全部解
阿新 • • 發佈:2018-11-02
#include"stdio.h"
int a[12][12]={0};//棋盤
int cut=0;//快取馬所走的步數
long count=0;//計算有多少種踏法
void horse(int x,int y);
bool walk(int index,int *x,int *y);
void print();
/*
馬每走一步就將該座標修改為踏的第幾格(如:第一格為1,第二格為2...)總共64格 踏完輸出
馬理論上不論在哪個點都有八個地方可走,為了防止空指標異常,給邊上加兩圈,
相當於從第二行到第九行,第二列到第九列,遍歷棋盤上的每一個點找到所有解 。
將八個位置存起來 每次準備踏的位置由 walk()計算,若能踏則計算出來,給該格賦值為第幾格
然後遞迴呼叫 horse()繼續前行,如果前行後發現無路可走,馬退回來(遞迴的那個函式結束,從棧中彈出),
然後清除剛才位置的標記,繼續遞迴.
踏完的標誌位cut=64,踏完後輸出 然後對剛才的位置進行擦除 直到遞迴結束
*/
int main()
{
for(int i=2;i<10;i++)
{
for(int j=2;j<10;j++)
{
//外面的兩層迴圈用於遍歷棋盤上的所有點
cut=0;
a[i][j]=++cut;//放馬
horse(i,j);//跑
a[i][j]=0;//跑完後擦除足跡
}
}
}
void horse(int x,int y)
{
bool resule=false;
for(int i=0;i<8;i++)//對馬的八個方向進行遍歷
{
if(walk(i,&x,&y))//判斷該方向是否能走
{
a[x][y]=++cut;//能走 上面的walk改變x,y的值到可以走的點 a[x][y]讓馬踏上來
if(cut==64)//結束條件
{
print();//輸出棋盤
a[x][y]=0;
cut--;
break;
}
else
{
horse(x,y);//能踏且沒結束 繼續前行
a[x][y]=0;//踏上去後無路可走 擦除剛才路的痕跡 繼續找路
cut--;
}
}
}
}
bool walk(int index,int *x,int *y)
{
int i=*x,j=*y;
bool result=false;
switch(index)//計算馬向各方向踏的座標
{
case 0:i=i+2,j=j+1;break;
case 1:i=i+1,j=j+2;break;
case 2:i=i-1,j=j+2;break;
case 3:i=i-2,j=j+1;break;
case 4:i=i-2,j=j-1;break;
case 5:i=i-1,j=j-2;break;
case 6:i=i+1,j=j-2;break;
case 7:i=i+2,j=j-1;break;
}
if(i>1&&i<10&&j>1&&j<10&&a[i][j]==0)//判斷該地方能不能踏
{ //能踏就將馬移到這個位置
*x=i;
*y=j;
result=true;
}
return result;
}
void print()
{
count++;
printf("count=%ld\n",count);
for(int i=2;i<10;i++)
{
for(int j=2;j<10;j++)
{
printf("%d\t",a[i][j]);
}
printf("\n\n");
}
printf("\n\n\n");
}
int a[12][12]={0};//棋盤
int cut=0;//快取馬所走的步數
long count=0;//計算有多少種踏法
void horse(int x,int y);
bool walk(int index,int *x,int *y);
void print();
/*
馬每走一步就將該座標修改為踏的第幾格(如:第一格為1,第二格為2...)總共64格 踏完輸出
馬理論上不論在哪個點都有八個地方可走,為了防止空指標異常,給邊上加兩圈,
相當於從第二行到第九行,第二列到第九列,遍歷棋盤上的每一個點找到所有解 。
將八個位置存起來 每次準備踏的位置由 walk()計算,若能踏則計算出來,給該格賦值為第幾格
然後遞迴呼叫 horse()繼續前行,如果前行後發現無路可走,馬退回來(遞迴的那個函式結束,從棧中彈出),
然後清除剛才位置的標記,繼續遞迴.
踏完的標誌位cut=64,踏完後輸出 然後對剛才的位置進行擦除 直到遞迴結束
*/
int main()
{
for(int i=2;i<10;i++)
{
for(int j=2;j<10;j++)
{
//外面的兩層迴圈用於遍歷棋盤上的所有點
cut=0;
a[i][j]=++cut;//放馬
horse(i,j);//跑
a[i][j]=0;//跑完後擦除足跡
}
}
}
void horse(int x,int y)
{
bool resule=false;
for(int i=0;i<8;i++)//對馬的八個方向進行遍歷
{
if(walk(i,&x,&y))//判斷該方向是否能走
{
a[x][y]=++cut;//能走 上面的walk改變x,y的值到可以走的點 a[x][y]讓馬踏上來
if(cut==64)//結束條件
{
print();//輸出棋盤
a[x][y]=0;
cut--;
break;
}
else
{
horse(x,y);//能踏且沒結束 繼續前行
a[x][y]=0;//踏上去後無路可走 擦除剛才路的痕跡 繼續找路
cut--;
}
}
}
}
bool walk(int index,int *x,int *y)
{
int i=*x,j=*y;
bool result=false;
switch(index)//計算馬向各方向踏的座標
{
case 0:i=i+2,j=j+1;break;
case 1:i=i+1,j=j+2;break;
case 2:i=i-1,j=j+2;break;
case 3:i=i-2,j=j+1;break;
case 4:i=i-2,j=j-1;break;
case 5:i=i-1,j=j-2;break;
case 6:i=i+1,j=j-2;break;
case 7:i=i+2,j=j-1;break;
}
if(i>1&&i<10&&j>1&&j<10&&a[i][j]==0)//判斷該地方能不能踏
{ //能踏就將馬移到這個位置
*x=i;
*y=j;
result=true;
}
return result;
}
void print()
{
count++;
printf("count=%ld\n",count);
for(int i=2;i<10;i++)
{
for(int j=2;j<10;j++)
{
printf("%d\t",a[i][j]);
}
printf("\n\n");
}
printf("\n\n\n");
}