骑士走棋盘【非递归,贪心,回溯】

  /*

1:骑士的走法:沿四个方向中的某个方向走两步,然后转90度,即“L”路线。

如果骑士当前座标是(i,j),骑士可走的位置包括(i+2,j+1)、(i+2,j-1)、

(i-2,j+1)、(i-2,j-1)、(i+1,j+2)、(i-1,j+2)、(i+1,j-2)、(i+1,j-2)八个

位置

2:8*8的棋盘至少走63步,如果用递归的话,就是嵌套至少63层循环,效率不高

3:用栈保存步骤,然后用回溯法。

4:如果人为控制棋子:

(1)记录当前位置,在可走的位置(根据当前位置计算)任选一个【选择步数最少

的一个(贪心算法?)】,移动棋子,并将选择的位置记录为走过的位置(修改标志

为1)

(2)终止条件:棋盘全部标记为1或者回到了初始位置之后没有可供选择的位置

(3)如果当前位置没有可走的位置,将当前位置标志置为0,并将棋子返回到当

前位置的上一个位置

*/

#include “stdio.h” typedef struct{

 int i;

 int j;

}SNode; int pass=1;    //记录走过的点数

SNode path[100];  //记录走过的路线

int step[64][9];  //记录每一步走过的下一步

int chessboard[8][8]; //棋盘

int test(int i,int j); //求(i,j)点下一步有几个落点

int Sln(int i,int j); //求解过程

void PrintBoard();  //打印棋盘

void main()

{

 if(Sln(0,0))

 {

  PrintBoard();

 }

 else

 {

  printf(“No solution!\n”);

 }

} //functions sections

int test(int i,int j)

{

 int x=0;

 if (i+2>=0 && i+2<=7 && j+1>=0 && j+1 <= 7&& chessboard[i+2][j+1] == 0) x++;

 if (i+2>=0 && i+2<=7 && j-1>=0 && j-1 <= 7&& chessboard[i+2][j-1] == 0) x++;

 if (i-2>=0 && i-2<=7 && j+1>=0 && j+1 <= 7&& chessboard[i-2][j+1] == 0) x++;

 if (i-2>=0 && i-2<=7 && j-1>=0 && j-1 <= 7&& chessboard[i-2][j-1] == 0) x++;

 if (i+1>=0 && i+1<=7 && j+2>=0 && j+2 <= 7&& chessboard[i+1][j+2] == 0) x++;

 if (i-1>=0 && i-1<=7 && j+2>=0 && j+2 <= 7&& chessboard[i-1][j+2] == 0) x++;

 if (i+1>=0 && i+1<=7 && j-2>=0 && j-2 <= 7&& chessboard[i+1][j-2] == 0) x++;

 if (i-1>=0 && i-1<=7 && j-2>=0 && j-2 <= 7&& chessboard[i-1][j-2] == 0) x++;

 return x;

}

int Sln(int x,int y)

{

 //1:如果走过的点不到64,确定供选择的且没有走过的点【最多8个】;

 //2:选择8个点中步数最少且没有试探过的点,当前点置1,走过去,走过的点+1,继续第1步;

 //3:如果没有可供选择的点,当前点置0,回到上一个点,继续第2步;  //(x,y)是第一个点

 int n,t,a,b,k;

 int ti,tj;

 int tx;

 pass = 1;

 path[pass].i = x;

 path[pass].j = y;

 chessboard[x][y] = 1;

 while (pass < 64 && pass > 0)

 {

  n=9;

  //确定当前点下一步的落点数并记录下一步落点最少的落点的位置

  ti = path[pass].i;

  tj = path[pass].j;

  for (k=1 ; k<= 8 ; k++)

  {

   switch(k)

   {

   case 1: 

    a = ti+2;b = tj+1;break;

   case 2:

    a = ti+2;b = tj-1;break;

   case 3:

    a = ti-2;b = tj+1;break;

   case 4: 

    a = ti-2;b =tj-1;break;

   case 5:

    a = ti+1;b = tj+2;break;

   case 6:

    a = ti-1;b = tj+2;break;

   case 7:

    a = ti+1;b = tj-2;break;

   case 8:

    a = ti-1;b = tj-2;break;

   }

   if (a>=0 && a<=7 && b>=0 && b<=7 && chessboard[a][b] == 0 && step[pass][k] != -1)

   {

    t = test(a,b);

    if (t<n)

    {

     step[pass][k] = -1;

     tx = k;

     n = t;

     path[pass+1].i = a;

     path[pass+1].j = b;

    }

   }   }  

  if (n!=9)

  {

   pass++;

   chessboard[path[pass].i][path[pass].j] = pass;

  }

  else

  {

   pass–;

  }

 }

 if (pass == 0) return 0; //如果pass=0,说明(x,y)点无路可走了~

 return 1;

}

void PrintBoard()

{

 int i,j;

 for (i=0;i<8;i++)

 {

  for (j=0;j<8;j++) printf(“%3d”,chessboard[i][j]);

  printf(“\n”);

 }

}

点赞