骑士游历
理论:
骑士游历问题是放在8×8的国际象棋棋盘上的一个马,按照马走"日"字的规则是否能够不重复地走遍棋盘的每个格。
解答:
简单的说,先将最难的位置走完,接下来的路就宽广了,骑士所要走的下一步,「为下一步再选择时,所能走的步数最少 的一步。」,使用这个方法,在不使用递归的情况下,可以有较高的机率找出走法(找不到走法的机会也是有的)。
java实现:
package 经典; public class Knight { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] board=new int[8][8]; Knight knight=new Knight(); if(knight.travel(4,4,board)) { System.out.println("骑士游历完成"); printArray(board); } else { System.out.println("骑士游历失败"); printArray(board); } } private static void printArray(int[][] board) { // TODO Auto-generated method stub for(int i=0; i<board.length; i++) { for( int j=0; j<board[i].length; j++) System.out.printf("%8d",board[i][j]); System.out.println(); } } public static boolean travel(int startx,int starty,int [][]board){ for(int i=0; i<board.length; i++) for(int j=0; j<board.length; j++) board[i][j]=0; int[] ktmovex={2,1,2,1,-2,-1,-2,-1}; int[] ktmovey={1,2,-1,-2,1,2,-1,-2}; int x=startx; int y=starty; board[startx][starty]=1; // 测试下一步的出路 int[] nextx=new int[board.length]; int[] nexty=new int[board.length]; // 记录出路的个数 int []exists=new int[board.length]; for(int i=0; i<board.length; i++) exists[i]=0; for(int i=2; i<Math.pow(board.length, 2); i++) { int count=0; int tempx; int tempy; for(int j=0; j<board.length; j++) { tempx=x+ktmovex[j]; tempy=y+ktmovey[j]; if(tempx<0 || tempx>7 || tempy<0 || tempy>7 ) continue; if(board[tempx][tempy]==0) { nextx[count]=tempx; nexty[count]=tempy; count++; } } int min=-1; if(count==0) return false; else if(count==1) min=0; else { for(int n=0; n<count; n++) { for(int m=0; m<board.length; m++) { tempx=nextx[n]+ktmovex[m]; tempy=nexty[n]+ktmovey[m]; if(tempx<0 || tempx>7|| tempy<0 || tempy>7 ) continue; if(board[tempx][tempy]==0) { exists[n]++; } } } } int temp=exists[0]; min=0; for(int k=1; k<count; k++) { if(temp>exists[k]) { temp=exists[k]; min=k; } } x=nextx[min]; y=nexty[min]; board[x][y]=i; } return true; } }