骑士游历

理论:

骑士游历问题是放在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;
    }
}

 

posted @ 2014-10-05 10:17  凡尘里的一根葱  阅读(887)  评论(0编辑  收藏  举报