骑士游历问题

Posted optor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了骑士游历问题相关的知识,希望对你有一定的参考价值。

由于最近在学习回溯法,所以跟回溯法相关的问题尽量都看下吧。
骑士游历问题的完整描述见:http://blog.csdn.net/sb___itfk/article/details/50905275

我的思路

我的实现如下,还是最简单最粗暴的解法:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by clearbug on 2018/2/26.
 */
public class Solution {

    public static void main(String[] args) {
        Solution s = new Solution();
        long startTime = System.currentTimeMillis();
        List<List<String>> res = s.traverse(5, 0, 0);
        int i = 1;
        for (List<String> item : res) {
            System.out.println("第 " + i + " 种走法:");
            for (String line : item) {
                System.out.println(line);
            }
            i++;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("运行耗时:" + (endTime - startTime) + " ms");
    }

    public List<List<String>> traverse(int N, int sr, int sc) {
        int[][] board = new int[N][N];
        board[sr][sc] = 1;

        List<List<String>> res = new ArrayList<>();
        dfs(board, sr, sc, res);
        return res;
    }

    private void dfs(int[][] board, int sr, int sc, List<List<String>> res) {
        if (check(board)) {
            List<String> lines = new ArrayList<>();
            for (int i = 0; i < board.length; i++) {
                lines.add(Arrays.toString(board[i]));
            }
            res.add(lines);
        }

        int[] dr = {2, 2, -2, -2, 1, 1, -1, -1};
        int[] dc = {1, -1, 1, -1, 2, -2, 2, -2};

        for (int i = 0; i < 8; i++) {
            int[][] newBoard = deepthCopy(board);
            int cr = sr + dr[i];
            int cc = sc + dc[i];
            if (cr >= 0 && cr < board.length && cc >= 0 && cc < board.length && board[cr][cc] == 0) {
                newBoard[cr][cc] = newBoard[sr][sc] + 1;
                dfs(newBoard, cr, cc, res);
            }
        }

    }

    private int[][] deepthCopy(int[][] board) {
        int[][] res = new int[board.length][board.length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                res[i][j] = board[i][j];
            }
        }
        return res;
    }
    
    private boolean check(int[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                if (board[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }

}

运行结果如下:

301 种走法:
[1, 16, 21, 6, 3]
[10, 5, 2, 15, 20]
[17, 22, 11, 4, 7]
[12, 9, 24, 19, 14]
[23, 18, 13, 8, 25]
第 302 种走法:
[1, 16, 11, 6, 3]
[10, 5, 2, 21, 12]
[15, 22, 17, 4, 7]
[18, 9, 24, 13, 20]
[23, 14, 19, 8, 25]
第 303 种走法:
[1, 16, 11, 6, 3]
[10, 5, 2, 17, 12]
[15, 22, 19, 4, 7]
[20, 9, 24, 13, 18]
[23, 14, 21, 8, 25]
第 304 种走法:
[1, 18, 11, 6, 3]
[10, 5, 2, 17, 12]
[19, 22, 13, 4, 7]
[14, 9, 24, 21, 16]
[23, 20, 15, 8, 25]
运行耗时:4073 ms

当 n = 5 时,运行时间已经上 4 秒了。。。可以虽然可以正确运行,但是效率并不 ok
那么,还是去看看 sb___itfk 这位老铁的解法吧:http://blog.csdn.net/sb___itfk/article/details/50905275

sb___itfk 解法

参考

http://blog.csdn.net/sb___itfk/article/details/50905275

以上是关于骑士游历问题的主要内容,如果未能解决你的问题,请参考以下文章

骑士游历问题(马踏棋盘)解析(c++)

骑士游历C语言递归,请大家帮忙看下哪里错了,谢谢

POJ 2488 -- A Knight's Journey(骑士游历)

你会97年的第三题骑士游历问题,跪求啊,救命用啊谢谢啊,回头给积分,要多少给多少,谢谢

HihoCoder 1504 : 骑士游历 (矩阵乘法)

codevs——T1219 骑士游历