Java演算法-「馬踏棋盤問題」

  1 /*
  2      * 馬踏棋盤問題:(貪婪法求解)
  3      * 棋盤有64個位置,“日”字走法,剛好走滿整個棋盤
  4      */
  5 
  6     //下一個走法的方向類
  7     class Direction{
  8         int x;
  9         int y;
 10         int wayOutNum;
 11     }
 12 
 13     public class Hores_chessboard_1 {
 14         static final int[] dx = { -2, -1, 1, 2, 2, 1, -1, -2 }; // x方向的增量  
 15         static final int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 }; // y方向的增量  
 16         static final int N = 8;     
 17         static int[][] chessboard = new int[N][N]; // 棋盤 
 18 
 19     /**
 20      * 
 21      * @param nami
 22      * @param x,y爲棋子的位置
 23      * @return 如果棋子的位置不合法,則返回一個大於8的數。
 24      * 否則返回棋子的下個出路的個數
 25      */
 26     static int wayOut(int x, int y){        
 27         int count = 0;
 28         int tx, ty, i;
 29         //判斷是否超出棋盤邊界,該位置是否已經下過
 30         if(x<0 || x>7 || y<0 || y>7 || chessboard[x][y]!=0){
 31             return 9;
 32         }
 33         for(i=0; i<N; i++){
 34             tx = x+dx[i];
 35             ty = y+dy[i];
 36             //如果棋子的下個出路可行,則出路數自加一次
 37             if(tx>-1 && tx<8 && ty>-1 && ty<8 && chessboard[tx][ty]==0)
 38                 count++;
 39         }
 40         return count;
 41     }
 42 
 43     /**
 44      * 按照棋子的下個出路的個數從低到高排序
 45      * @param next 棋子的八個位置的數組
 46      */
 47     static void sort(Direction[] next){
 48         int i, j, index;
 49         Direction temp = null;
 50         //這裏用的選擇排序
 51         for(i=0; i<N; i++){
 52             index = i;
 53             for(j=i+1; j<N; j++){
 54                 if(next[index].wayOutNum > next[j].wayOutNum)
 55                     index = j;
 56             }
 57             if(i != index){
 58                 temp = next[i];
 59                 next[i] = next[index];
 60                 next[index] = temp;
 61             }
 62         }
 63     }
 64 
 65     static void Move(int x, int y, int step){
 66         int i, j;
 67         int tx, ty;
 68         //如果step==64,則說明每個棋格都走到了,現在只需要打印結果就完了
 69         if(step == N*N){
 70             for(i=0; i<N; i++){
 71                 for(j=0; j<N; j++){
 72                     System.out.printf("%3d", chessboard[i][j]);
 73                 }
 74                 System.out.println();
 75             }
 76             System.exit(0);
 77         }
 78 
 79         //下一個棋子的N個位置的數組
 80         Direction[] next = new Direction[N];
 81 
 82         for(i=0; i<N; i++){
 83             Direction temp = new Direction();
 84             temp.x = x+dx[i];
 85             temp.y = y+dy[i];
 86             next[i] = temp;
 87             //循環得到下個棋子N處位置的下個出路的個數
 88             next[i].wayOutNum = wayOut(temp.x, temp.y);
 89         }
 90 
 91         //配合貪婪算法,按下個棋子的下個出路數排序後,next[0]就是下個出路數最少的那個
 92         sort(next);
 93 
 94         for(i=0; i<N; i++){
 95             tx = next[i].x;
 96             ty = next[i].y;
 97             chessboard[tx][ty] = step;
 98             Move(tx, ty, step+1);
 99             /*如果上面Move()往下一步走不通,則回溯到這裏
100             重置chessboard[tx][ty]爲0,接着i++,又循環...... */
101             chessboard[tx][ty] = 0;
102         }
103     }
104 
105     public static void main(String[] args) {
106         int i, j;
107         //初始化棋盤
108         for(i=0; i<8; i++){
109             for(j=0; j<8; j++){
110                 chessboard[i][j] = 0;
111             }
112         }
113         System.out.println("請輸入棋子開始位置(0-7):");
114         Scanner sc = new Scanner(System.in);
115         int x = sc.nextInt();
116         int y = sc.nextInt();
117         //第一步不用比較,賦值第一步
118         chessboard[x][y] = 1;
119         Move(x, y, 2);      
120     }
121 }

 

posted @ 2017-01-11 14:35  少於無  阅读(194)  评论(0)    收藏  举报