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

来源:互联网 发布:淘宝刷单一天能赚多少 编辑:程序博客网 时间:2024/05/01 08:35
 
/*
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");
 }
}
原创粉丝点击