1. 程式人生 > >馬踏棋盤全部解

馬踏棋盤全部解

#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");
}