残缺的棋盘-分治法【java】

题目描述:

使用分治法求解棋盘覆盖问题

棋盘覆盖问题的描述:

 

 

 残缺位置所在的四种不同情况:

 

/**
 * 二分法不相似情况:残缺棋盘
 *   by
 * 小俱的一步步
 */
public class CanquedeQP {

    private int size;
    private int[][] board;
    //所使用三格板的数目
    private int amount;

    /**
     * 初始化board
     * @param size 行、列的长度
     */
    public CanquedeQP(int size){
        this.amount = 0;
        this.size = size;
        this.board = new int[this.size][this.size];
    }

    public static void main(String[] args) {
        CanquedeQP canquedeQP = new CanquedeQP(16);
        canquedeQP.cover(16,0,0,5,8);
        System.out.println(canquedeQP);
    }

    /**
     * 分治覆盖法
     * @param size 方形棋盘的长宽
     * @param tr 子棋盘左上角方格所在行
     * @param tc 子棋盘左上角方格所在列
     * @param dr 残缺方格所在行
     * @param dc 残缺方格所在列
     */
    public void cover(int size,int tr,int tc,int dr,int dc){
        //当分隔为一个方块时,返回
        if (size==1){
            return;
        }
        this.amount++;
        int t = this.amount;
        size = size/2;
        //左上
        if (dr<(tr+size) && dc<(tc+size)){
            cover(size,tr,tc,dr,dc);
            board[tr+size-1][tc+size] = t;
            board[tr+size][tc+size-1] = t;
            board[tr+size][tc+size] = t;
            //覆盖其余部分
            cover(size,tr,tc+size,tr+size-1,tc+size);
            cover(size,tr+size,tc,tr+size,tc+size-1);
            cover(size,tr+size,tc+size,tr+size,tc+size);
        //右上
        }else if (dr<(tr+size)&& dc>=(tc+size)){
            cover(size,tr,tc+size,dr,dc);
            board[tr+size-1][tc+size-1] = t;
            board[tr+size][tc+size-1] = t;
            board[tr+size][tc+size] = t;
            //覆盖其余部分
            cover(size,tr,tc,tr+size-1,tc+size-1);
            cover(size,tr+size,tc,tr+size,tc+size-1);
            cover(size,tr+size,tc+size,tr+size,tc+size);
        //左下
        }else if (dr>=(tr+size) && dc<(tc+size)) {
            cover(size, tr + size, tc, dr, dc);
            board[tr + size - 1][tc + size - 1] = t;
            board[tr + size - 1][tc +size] = t;
            board[tr + size][tc + size] = t;
            //覆盖其余部分
            cover(size, tr, tc, tr + size - 1, tc +size - 1);
            cover(size, tr, tc + size, tr + size - 1, tc +size);
            cover(size, tr + size, tc + size, tr +size, tc + size);
        //右下
        }else if (dr>=(tr+size) && dc>=(tc+size)) {
            cover(size, tr+size, tc + size, dr, dc);
            board[tr + size - 1][tc + size - 1] = t;
            board[tr + size-1][tc + size] = t;
            board[tr + size][tc + size-1] = t;
            //覆盖其余部分
            cover(size, tr, tc, tr + size - 1, tc + size - 1);
            cover(size, tr , tc+size, tr + size-1, tc + size );
            cover(size, tr + size, tc , tr + size, tc + size-1);
        }
    }

    @Override
    public String toString() {
        String res = "";
        for (int i = 0; i < this.size ; i++) {
            for (int j = 0; j <this.size ; j++) {
                res= res+this.board[i][j]+"\t";
            }
            res = res+"\n";
        }
        return res;
    }
}

测试为16*16的方格残缺位置为【5,8】,输出结果为:

在Python中,使用分治法解决残缺棋盘问题(通常是类似“N皇后”问题的变种),可以按照以下步骤来进行: 1. **定义问题**:首先,你需要定义一个函数,接受一个二维数组表示的残缺棋盘和一个目标数N(代表需要放置的皇后数量)。这个数组可以是0(表示空格)和非零值(表示已存在的障碍)。 2. **基础情况**:如果残缺棋盘大小为1,或者障碍的数量等于剩余需要放置的皇后数量,则直接返回一个列表,只包含一个元素,表示唯一合法的位置。 3. **分割**:将棋盘一分为二,分别处理左半部分和右半部分。这通常意味着将棋盘的宽度减半,并分别寻找各自的解。 4. **递归**:对于每一部分棋盘,调用自身,尝试在其子棋盘上放置皇后。同时,记录下当前已经放置了的皇后的坐标。 5. **合并**:当得到左右两部分的解后,检查它们是否能并存(即它们之间的距离足够大,避免冲突)。如果可以,就将这两个解合并在一起,生成新的解集。 6. **回溯**:如果不满足条件(如有冲突),就需要回溯到上一步,尝试下一个可能的位置。 7. **返回结果**:最后,当所有的皇后都被成功放置并且没有冲突时,返回结果。 下面是一个简单的伪代码示例: ```python def solve(board, remaining): # ... 具体实现细节 ... def n_queens(board_size, n): if n == 1 or board_size == 1: return [1] # 分治处理 half_board_size = board_size // 2 left_solutions = n_queens(half_board_size, n) right_solutions = n_queens(half_board_size, n - 1) # 减去一个皇后 solutions = [] for left_solution in left_solutions: for right_solution in right_solutions: # 合并左右解,检查是否有冲突 merged_board = merge(left_solution, right_solution, board_size) if is_valid(merged_board): solutions.append(merged_board) return solutions ``` 注意,以上代码仅给出了大致思路,实际编写时需处理具体的棋盘操作和冲突检测逻辑。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小俱的一步步

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

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

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

打赏作者

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

抵扣说明:

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

余额充值