回溯算法的应用

迷宫问题

在这里插入图片描述

利用栈来进行回溯

public class Maze {
    private static int[][] maze = {
            {1, 1, 1, 1, 1, 1, 1, 1, 1},
            {0, 0, 1, 0, 0, 0, 1, 1, 1},
            {1, 0, 1, 1, 1, 0, 1, 1, 1},
            {1, 0, 0, 1, 0, 0, 1, 1, 1},
            {1, 1, 0, 1, 1, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 1, 0, 1},
            {1, 0, 1, 1, 1, 0, 0, 0, 1},
            {1, 1, 0, 0, 0, 0, 1, 0, 0},
            {1, 1, 1, 1, 1, 1, 1, 1, 1}
    };

    private static int entryX = 1;
    private static int entryY = 0;

    private static int exitX = 7;
    private static int exitY = 8;

    private static boolean[][] vistied = new boolean[9][9];

    private static int direction[][] = {
            {-1,0},{0,1},{1,0},{0,-1}
    };

    private static LinkedList<String> stack = new LinkedList<>();

    public static void main(String[] args) {
        boolean fiag = go(entryX,entryY);
        if(fiag) System.out.println(stack);
    }

    private static boolean go(int x, int y) {
        stack.push("(" + x + "," + y + ")");
        vistied[x][y] = true;
        if(x == exitX && y == exitY){
            return true;
        }

        for(int i = 0; i < direction.length; i++){
            int newx = direction[i][0] + x;
            int newy = direction[i][1] + y;
            if(isInArea(newx,newy) && isRoad(newx,newy) && !vistied[newx][newy]){
                if(go(newx,newy))
                    return true;
            }
        }
        return false;
    }

    private static boolean isRoad(int x, int y) {
        return maze[x][y] == 0;
    }

    private static boolean isInArea(int x, int y) {
        return x >= 0 && x < 9 && y >= 0 && y < 9;
    }
}

N皇后问题

public class NQueen {
    private static int count = 0;
    private static final int N = 4;
    private static int[][] arr = new int[N][N];

    public static void main(String[] args) {
        queen(0);
    }

    private static void queen(int row) {
        if (row == N) {
            count++;
            System.out.println("第" + count + "解");
            printArr();
        } else {
            for (int col = 0; col < N; col++) {
                if (!isDangerous(row, col)) {
                    for (int c = 0; c < N; c++) {
                        arr[row][c] = 0;
                    }
                    arr[row][col] = 1;
                    queen(row + 1);
                }
            }
        }
    }

    private static boolean isDangerous(int row, int col) {
        for (int r = row - 1; r >= 0; r--) {
            if (arr[r][col] == 1) {
                return true;
            }
        }

        for (int r = row - 1, c = col - 1; r >= 0 && c >= 0; r--, c--) {
            if (arr[r][c] == 1) {
                return true;
            }
        }
        for (int r = row - 1, c = col + 1; r >= 0 && c < N; r--, c++) {
            if (arr[r][c] == 1) {
                return true;
            }
        }
        return false;
    }

    private static void printArr() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

数独问题

005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700

通过I/O流来获取数独

private static void readDile(String s) throws IOException {
    File file = new File(s);
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);
    String line = null;
    int row = 0;
    while ((line = br.readLine()) != null){
        for(int col = 0; col < 9; col++){
            board[row][col] = Integer.parseInt(line.charAt(col) + "");
        }
        row++;
    }
}

破解数独

public class Sudoku {

    private static int i = 0;
    private static int[][] board = new int[9][9];
    public static void main(String[] args) throws IOException {
        readDile("sododata.txt");     
        solve(0,0);
    }

    private static void solve(int row, int col) {
        if(row == 9){
            printBoard();
        }else{
            if(board[row][col] == 0){
                for(int i = 1; i <= 9; i++){
                    if(!isExist(row, col, i)){
                        board[row][col] = i;
                        solve(row + (col + 1) / 9, (col + 1) % 9);
                    }
                    board[row][col] = 0;
                }
            }else{
                solve(row + (col + 1) / 9, (col + 1) % 9);
            }
        }
    }

    private static boolean isExist(int row, int col, int i) {
        for(int c = 0; c < 9; c++){
            if(board[row][c] == i){
                return true;
            }
        }

        for(int r = 0; r < 9; r++){
            if(board[r][col] == i){
                return true;
            }
        }

        int rowMin = 0;
        int colMin = 0;
        int rowMax = 0;
        int colMax = 0;

        if(row >= 0 && row <= 2){
            rowMin = 0;
            rowMax = 2;
        }
        if(row >= 3 && row <= 5){
            rowMin = 3;
            rowMax = 5;
        }
        if(row >= 6 && row <= 8){
            rowMin = 6;
            rowMax = 8;
        }
        if(col >= 0 && col <= 2){
            colMin = 0;
            colMax = 2;
        }
        if(col >= 3 && col <= 5){
            colMin = 3;
            colMax = 5;
        }
        if(col >= 6 && col <= 8){
            colMin = 6;
            colMax = 8;
        }
        for(int r = rowMin; r <= rowMax; r++){
            for(int c = colMin; c <= colMax; c++){
                if(board[r][c] == i){
                    return true;
                }
            }
        }
        return false;
    }

    private static void printBoard() {
        for(int i = 0; i < 9; i++){
            for(int j = 0; j < 9; j++){
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }

    private static void readDile(String s) throws IOException {
        File file = new File(s);
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        String line = null;
        int row = 0;
        while ((line = br.readLine()) != null){
            for(int col = 0; col < 9; col++){
                board[row][col] = Integer.parseInt(line.charAt(col) + "");
            }
            row++;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值