理論:
騎士遊曆問題是放在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;
}
}
轉載于:https://www.cnblogs.com/huangcongcong/p/4006759.html