分治回溯应用题整理

1.迷宫问题

package 分治回溯;

import java.util.LinkedList;

//迷宫
public class Maze {
    private static int[][] maze = {
            {1,1,1,1,1,1,1,1,1},
            {0,0,1,1,1,1,1,1,1},
            {1,0,1,0,0,0,1,1,1},
            {1,0,0,0,1,1,1,1,1},
            {1,0,1,0,1,0,1,1,1},
            {1,0,0,0,0,0,1,1,1},
            {1,1,0,1,1,0,0,0,1},
            {1,1,1,1,1,0,1,0,0},
            {1,1,1,1,1,1,1,1,1},
    };
    private static int enterX = 1;
    private static int enterY = 0;//入口
    private static int exitX = 7;
    private static int exitY = 8;//出口

    private static boolean[][] visited = 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) {
        go(enterX,enterY);
        while(!stack.isEmpty()){
            System.out.println(stack.pop());
        }
    }

    private static boolean go(int x, int y) {
        stack.push("(" + x + "," + y + ")");
        visited[x][y] = true;
        if (x == exitX && y == exitY){
            return true;
        }
        for (int i = 0;i < direction.length;i++){
            int newX = x + direction[i][0];
            int newY = y + direction[i][1];
            if (isInMaze(newX,newY) && isRoad(newX,newY) && !visited[newX][newY]){
                if (go(newX, newY)) {
                    return true;
                }
            }
        }
        stack.pop();
        return false;
    }

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

    private static boolean isInMaze(int newX, int newY) {
        return newX >= 0 && newX < 9 && newY >= 0 && newY < 9;
    }
}

2.全排列问题

package 分治回溯;

import java.util.TreeSet;

//全排列
public class FullPermutation {

    public static void main(String[] args) {
        String s = "ABC";
        char[] arr = s.toCharArray();
        permutation(arr,0,arr.length - 1);
    }

    private static void permutation(char[] arr,int from,int to) {
        if (from == to){
            System.out.println(String.valueOf(arr));
        }
        for(int i = from;i <= to;i++){
            swap(arr,i,from);
            permutation(arr,from + 1,to);
            swap(arr,i,from);
        }
    }

    private static void swap(char[] arr, int a, int b) {
        char temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
   /*
   *  private static TreeSet<String> set = new TreeSet<>();
    public static void main(String[] args) {
        String s = "ABC";
        char[] arr = s.toCharArray();
        permutation(arr,0,arr.length - 1);
        for (String s1:set) {
            System.out.println(s1);
        }
    }

    private static void permutation(char[] arr, int from, int to) {
        if (from == to) {
            set.add(String.valueOf(arr));
        }
        for (int i = from; i <= to; i++){
            swap(arr,i,from);
            permutation(arr,from + 1, to);
            swap(arr,i,from);
        }
    }

    private static void swap(char[] arr, int a, int b) {
        char temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
   * */
}

3.棋盘覆盖问题

package 分治回溯;
//棋盘覆盖
public class ChessboardCoverage {
    private static int BOARD_SIZE = 8;
    private static int[][] arr = new int[BOARD_SIZE][BOARD_SIZE];
    private static int title = 0;
    public static void main(String[] args) {

        int dr = 2;
        int dc = 3;//特殊方格坐标
        chessBoard(0,0,dr - 1,dc - 1,BOARD_SIZE);
        for (int i = 0;i < BOARD_SIZE;i++){
            for (int j = 0;j < BOARD_SIZE;j++){
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
    }

    private static void chessBoard(int tr,int tc,int dr,int dc,int size) {
        if (size == 1){
            return;
        }
        int num = ++title;
        int s = size / 2;
        //左上角
        if (dr < tr + s && dc < tc + s){
            chessBoard(tr,tc,dr,dc,s);
        }else {
            arr[tr + s - 1][tc + s - 1] = num;
            chessBoard(tr,tc,tr + s - 1,tc + s - 1,s);
        }
        //右上角
        if(dr < tr + s && dc >= tc + s){
            chessBoard(tr,tc + s,dr,dc,s);
        }else {
            arr[tr + s - 1][tc + s ] = num;
            chessBoard(tr,tc + s,tr + s - 1,tc + s,s);
        }
        //左下角
        if(dr >= tr + s && dc < tc + s){
            chessBoard(tr + s,tc,dr,dc,s);
        }else {
            arr[tr + s][tc + s - 1] = num;
            chessBoard(tr + s,tc,tr + s,tc + s - 1,s);
        }
        //右下角
        if (dr >= tr + s && dc >= tc + s){
            chessBoard(tr + s,tc + s,dr,dc,s);
        }else {
            arr[tr + s][tc + s] = num;
            chessBoard(tr + s,tc + s,tr + s,tc + s,s);
        }
    }
}

4.汉诺塔问题

package 分治回溯;
//汉诺塔

public class Hanoi {
    public static void main(String[] args) {
        String x = "x";
        String y = "Y";
        String z = "Z";
        hanoi(3,x,y,z);
    }

    private static void hanoi(int level,String begin,String mid,String to) {
        if (level == 1){
            System.out.println(begin + "->" + to);
        }
        else {
            hanoi(level - 1,begin,to,mid);
            System.out.println(begin + "->" + to);
            hanoi(level - 1,mid,begin,to);
        }
    }
}

5.N皇后问题

package 分治回溯;
//N皇后
public class Queen {
    private static int SIZE = 8;
    private static int count = 0;
    public static void main(String[] args) {
        int[][] arr = new int[SIZE][SIZE];
        queen(0,arr);
    }

    private static void queen(int row, int[][] arr) {
        if (row == SIZE){
            count++;
            System.out.println("第" + count + "种解");
            print(arr);
        }else {
            int[][] newArr = copyOf(arr);
            for(int col = 0; col < SIZE;col++){
                if (noDangerous(row,col,newArr)){
                    for (int c = 0; c < SIZE;c++){//如果安全的话,先将同行所有位置清空
                        newArr[row][c] = 0;
                    }
                    newArr[row][col] = 1;
                    queen(row + 1,newArr);
                }
            }
        }
    }

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

    private static boolean noDangerous(int row, int col, int[][] arr) {
        //正上方
        for (int r = row - 1;r >= 0;r--){
            if (arr[r][col] == 1){
                return false;
            }
        }
        //左上方
        for (int r = row - 1,c = col - 1;r >= 0 && c >= 0;r--,c--){
            if (arr[r][c] == 1){
                return false;
            }
        }
        //右上方
        for (int r = row - 1,c = col + 1;r >= 0 && c < SIZE;r--,c++){
            if (arr[r][c] == 1){
                return false;
            }
        }
        return true;
    }

    private static int[][] copyOf(int[][] arr) {
        int[][] newArr = new int[SIZE][SIZE];
        for (int i = 0;i < SIZE;i++){
            for (int j = 0;j < SIZE;j++){
                newArr[i][j] = arr[i][j];
            }
        }
        return newArr;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秀发嚯嚯没

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值