骑士周游 探索访问

困扰了我4天时间,差点被它打到!  终于找到了一种算法:探索访问

每个格子有8种移动结果,即移动后有8种位置,当然,有些靠棋盘边界的格子移动后的位置会在棋盘外面

用二维数组visit level的值表示棋盘每格的访问级别,这是个逆向思维的过程,一个格子能有几种合法方式(不超越棋盘界限,移动一步的值在0--7之间)移动到其它格子,这个格子的访问级别就越高,访问级别越高,访问它的难度越低,因此访问级别低的格子要优先访问。用一个for循环7*7*8次去移动格子,其中7*7对应每个格子,8对应每个格子的移动方法,如果移动后没有越界,格子的访问级别加1

用二位数组moveways记录每个格子的具体8种移动方式的合法情况,没一排为一个格子,共0--63个格子,每列8个元素为8种移动方法,用上面for7*7*8的同一个循环,可以创建每一格格子每种移动的合法情况,1为合法,0为非法

用函数boardtotal来检测board二维数组的总值,如果为64,则while循环结束

在while循环中比较当前位置几种合法走法的最优路径,并依据此路径确定下一步及位置。原则是每次访问最低访问等级的格子且格子的值为1(初始化为0,表示没有被访问过)。在确定下一步是把当前格子对应board二维数组的值设为1.


#include<stdio.h>
#define row 8
#define column 8
int boardtotal(int[][column]);
int main(){
 int board[row][column] = { 1 };
 int visitLevel[row][column] = { 0 };
 int horizontal[8] = { 2, 1, -1, -2, -2, -1, 1, 2 };
 int vertical[8] = { -1, -2, -2, -1, 1, 2, 2, 1 };
 int moveways[64][8] = { 0 };
 int  startrow, startcolumn , movestyle = 0,grid=0,best=9;
 int currentrow, currentcolumn,x=0,y=0;
 //Creat visit level&ways of each grid
 for (startrow = 0; startrow<=7; startrow++){
  for (startcolumn = 0; startcolumn<=7; startcolumn++){
   for (movestyle = 0; movestyle <= 7; movestyle++){
    if (startrow + vertical[movestyle] >= 0 &&
     startrow + vertical[movestyle] <= 7 &&
     startcolumn + horizontal[movestyle] >= 0 &&
     startcolumn + horizontal[movestyle] <= 7){
     visitLevel[startrow][startcolumn]++;
     moveways[grid][movestyle] = 1;
    }
   }
   grid++;
  }
 }//creat visit level&ways of each grid finish
 //print level form
 printf("********** visit level of each grid **********\n");
 printf("(the bigger the visitvalue, the easier to visit, \n");
 printf("so must visit the small value grid first)\n\n");
 for (x = 0; x <= 7; x++){
  for (y = 0; y <= 7; y++){
   printf("%d  ", visitLevel[x][y]);
  }
  printf("\n");
 }
 printf("-------------------------------------------------------------------------");
 //print ways of each grid
 printf("\n\n\n**********the move right of each grid**********\n");
 printf("(each grid has 8 move right,but not every right is legal\n");
 printf("the legal move can't overstep the boundary of the cheeseboard\n");
 printf("each grid(row) try each move righ(column),and assign 1 to the legal move)\n\n");
 for (x = 0; x <= 63; x++){
  for (y = 0; y <= 7; y++)
   printf("%d   ", moveways[x][y]);
  printf("\n");
 }
 printf("-------------------------------------------------------------------------");
 printf("\n\n     ***************Let's begin the knight's travel***************\n");
 printf("enter the start row location:");
 scanf("%d", &startrow);
 printf("enter the start column location:");
 scanf("%d", &startcolumn);
 grid = 8 * startrow + startcolumn;//translate to array "moveways"
 printf("Knight'travel begin from row[%d],column[%d]\n", startrow, startcolumn);
 while (boardtotal(board) != 64){//once one grid visited,the grid's
  //boardvalue will assign to 1,aft one step(one loop of while),
  //boardtotal()will check and return total boardvalue,when it became 64
  //loop stop,means the knight visited all grid of the fucking cheeseboard!
  for (movestyle = 0; movestyle <= 7; movestyle++){//try 8 move rights
   if (moveways[grid][movestyle] == 1){//see if the way of move rights leagle
    if (visitLevel[startrow + vertical[movestyle]]//must visit the smallest visit value
     [startcolumn + horizontal[movestyle]] <= best&&//compare value
     board[startrow + vertical[movestyle]]//avoid visiting the visited grid again
     [startcolumn + horizontal[movestyle]] == 0){
     currentrow = startrow + vertical[movestyle];
     currentcolumn = startcolumn + horizontal[movestyle];
     best = visitLevel[currentrow][currentcolumn];
    }
   }
  }
  startrow = currentrow;//aft compare 8 ways,confirm the best way
  startcolumn = currentcolumn;//also confirm new start location
  best = 9;//initialize for next round
  grid = 8 * currentrow + currentcolumn;//translate
  board[currentrow][currentcolumn] = 1;//mark the visited grid with 1,others is 0
  printf("\n→row[%d],column[%d],boardtotal[%d]\n",//print the step,total board value
   currentrow, currentcolumn, boardtotal(board));
  //down the level related to current grid(will be locked!)
  //the visit value of grid A means how many other grids can visit it
  //so once the grid which can visit grid A became the visited one
  //the visit value of grid A must minus 1
  for (movestyle = 0; movestyle <= 7; movestyle++){
   if (moveways[grid][movestyle] == 1)//the grid which the visited grid can visit
    visitLevel[currentrow + vertical[movestyle]]
    [currentcolumn + horizontal[movestyle]]--;
  }
 }
}
int boardtotal(int board[][column]){
 int x = 0, y = 0, d = 0;
 for (x = 0; x <= row - 1; x++){
  for (y = 0; y <= column - 1; y++)
   d = d + board[x][y];
 }
 return d;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值