棋盘覆盖问题

棋盘覆盖问题

1. 问题阐述

img
img

2. 问题解析

    我们主要用分治法来解决此问题。
        1.  我们首先可以将棋盘分割为四个(2^(k-1),2^(k-1))的子棋盘。
        2.  由于在分割之前,一个棋盘当中只会有一个特殊格子。当分割之后,只有一个子棋盘中存在特殊格子。
        3.  对于每一个子棋盘,我们依次需要判断:如果当前子棋盘存在特殊格子,那么直接递归处理即可。如果当前子棋盘不存在特殊格子,则需要使用L形骨牌来覆盖,以生成特殊格子。覆盖之后,直接递归处理即可。、
        4.  如果当前棋盘为1x1,那么已经到了无法覆盖的情况(边界情况),直接退出即可。

img
img

3. 代码

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 10000;
//代表棋盘
int chessboard[N][N];
//代表棋盘大小(保证2的次幂)
int s;
//代表棋盘内的特殊格子的坐标
int dr,dc;
//代表L形骨牌个数(编号)
int t;
//tr,tc代表当前棋盘左上角坐标,dr,dc代表当前棋盘内特殊格子的坐标,s代表当前棋盘大小
void algorithm(int tr,int tc,int dr,int dc,int s){
    //t1代表骨牌编号
    int t1;
    //如果当前棋盘为1x1,那么这个格子就是特殊格子,无法进行覆盖。
    if(s == 1){
        return;
    }
    //编号累加(在当前层中使用的都是同一个L形骨牌)
    t1 = ++t;
    //将棋盘进行分割
    s = s / 2;
    //如果特殊格子出现在左上角棋盘
    if(dr < tr + s && dc < tc + s){
        //进行递归处理
        algorithm(tr,tc,dr,dc,s);
    }else{
        //针对左上角棋盘的右下角进行覆盖
        chessboard[tr+s-1][tc+s-1] = t1;
        //进行递归处理
        algorithm(tr,tc,tr+s-1,tc+s-1,s);
    }
    //如果特殊格子出现在右上角棋盘
    if(dr < tr + s && dc >= tc + s){
        //进行递归处理
        algorithm(tr,tc+s,dr,dc,s);
    }else{
        //针对右上角棋盘的左下角进行覆盖
        chessboard[tr+s-1][tc+s] = t1;
        algorithm(tr,tc+s,tr+s-1,tc+s,s);
    }
    //如果特殊格子出现在左下角棋盘
    if(dr >= tr + s && dc < tc + s){
        //进行递归处理
        algorithm(tr+s,tc,dr,dc,s);
    }else{
        //针对左下角棋盘的右上角进行覆盖
        chessboard[tr+s][tc+s-1] = t1;
        algorithm(tr+s,tc,tr+s,tc+s-1,s);
    }
    //如果特殊格子出现在右下角棋盘
    if(dr >= tr +s && dc >= tc + s){
        //进行递归处理
        algorithm(tr+s,tc+s,dr,dc,s);
    }else{
        //针对右下角棋盘的左上角进行覆盖
        chessboard[tr+s][tc+s] = t1;
        //进行递归处理
        algorithm(tr+s,tc+s,tr+s,tc+s,s);
    }
}

int main(){
    //输入内容(大小,特殊格子的位置)
    scanf("%d%d%d",&s,&dr,&dc);
    //调用算法进行分治处理
    algorithm(0,0,dr,dc,s);
    for(int i = 0; i < s;i ++){
        for(int j = 0; j < s;j ++){
            printf("%d\t",chessboard[i][j]);
        }
        printf("\n");
    }
    return 0;
}

img

    上图为:棋盘的大小为8x8,特殊格子的位置为(3,3)时的执行情况。(下标从0开始)

img
img
img
img
img

4. 参考文献

    1.  上图的课件来自于中国科学院大学马丙鹏老师的计算机算法设计与分析课程。
    2.  https://baike.baidu.com/item/%E6%A3%8B%E7%9B%98%E8%A6%86%E7%9B%96%E9%97%AE%E9%A2%98/3015357?fr=ge_ala
posted @   夏目^_^  阅读(247)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示