棋盘覆盖问题——分治法

这篇具有很好参考价值的文章主要介绍了棋盘覆盖问题——分治法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

有一个 x<img src="https://latex.codecogs.com/gif.latex?2%5Ek" alt="2^k" class="mathcode" /> (k>0)的棋盘,恰好有一个方格与其他方格不同,称之为特殊方格。现在要用如下图所示的L形骨牌覆盖除了特殊方格以外的其他全部方格,骨牌可以任意旋转,并且任何两个骨牌不能重复。请给出一种覆盖方式。

棋盘覆盖问题——分治法

 

样例:

输入:

 

输出:

 

 

思路——分治法:

将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。

递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解。

就是将规模为n的问题自顶向下分解,直到小问题分解到足够小,可以解决时,再自底向上合并,从而得到原来的解。

 

当k=0(棋盘只有1格),特殊点只能唯一,L骨牌数为0

当k >0,则可将 2*kⅹ2*k 棋盘分割为 4个 2*k-1ⅹ2*k-1 的子棋盘

棋盘覆盖问题——分治法

判断特殊点在哪一个子棋盘中,用一块L骨牌放在其它三个子棋盘的连接处

以此类推,则最后可将每个子棋盘划分为1格的棋盘,结束递归

 

代码实现:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <iomanip>
using namespace std;

int arr[1000][1000];
int num = 0;
void ChessBoard(int x, int y, int a, int b, int length);

int main() {
    //棋盘大小
    int k;
    int length;
    cout << "请输入k:";
    cin >> k;
    length = pow(2,k);

    //空白点坐标
    int a, b;
    cout << "请输入空格位置:";
    cin >> a >> b;
    cout << endl;

    arr[a][b] = 0;//标点用0表示
    ChessBoard(1, 1, a, b, length);
    cout << setw(5);
    for (int i = 1; i <= length; i++) {
        for (int j = 1; j <= length; j++) {
            cout << arr[i][j] << setw(5);
        }
        cout << endl;
    }
    return 0;
}

void ChessBoard(int x, int y, int a, int b, int length) {
    if (length == 1) {
        return;
    }
    int h = length / 2;//分割棋盘
    int t = ++num;//骨牌号,从1开始,相同数字代表是同一块

    //以“田”的左下角为(1,1)
    //左下角
    if (a < x + h && b < y + h) {
        ChessBoard(x, y, a, b, h);
    }
    else {
        arr[x + h - 1][y + h - 1] = t;
        ChessBoard(x, y, x + h - 1, y + h - 1, h);
    }

    //左上角
    if (a < x + h && b >= y + h) {
        ChessBoard(x, y + h, a, b, h);
    }
    else {
        arr[x + h - 1][y + h] = t;
        ChessBoard(x, y + h, x + h - 1, y + h, h);
    }

    //右下角
    if (a >= x + h && b < y + h) {
        ChessBoard(x + h, y, a, b, h);
    }
    else {
        arr[x + h][y + h - 1] = t;
        ChessBoard(x + h, y, x + h, y + h - 1, h);
    }

    //右上角
    if (a >= x + h && b >= y + h) {
        ChessBoard(x + h, y + h, a, b, h);
    }
    else {
        arr[x + h][y + h] = t;
        ChessBoard(x + h, y + h, x + h, y + h, h);
    }
}

参考资料:《计算机算法设计与分析(第四版)》  文章来源地址https://www.toymoban.com/news/detail-425284.html

到了这里,关于棋盘覆盖问题——分治法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Leetcode 1812。判断国际象棋棋盘中一个格子的颜色

    给你一个坐标  coordinates  ,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。下图是国际象棋棋盘示意图。 如果所给格子的颜色是白色,请你返回  true ,如果是黑色,请返回  false  。 给定坐标一定代表国际象棋棋盘上一个存在的格子。坐标第一个字符是字母,第

    2024年02月11日
    浏览(35)
  • 棋盘问题

    【问题描述】 小蓝拥有 n × n 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了m次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色,黑色棋子变为白色)。 请输出所有操作做完后棋盘上每个棋子的颜色。 【输入格式】 输入的第一行包

    2024年02月04日
    浏览(29)
  • 2、有序链表的维护【问题描述】编写一个程序,根据从标准输入接收的指令来维护和操作排序的链表(C语言、java和Python分别实现)

    【问题描述】 编写一个程序,根据从标准输入接收的指令来维护和操作排序的链表。链表是按顺 序维护的,这意味着链表中的数据在每次操作后都以递增的数字顺序存储。 请注意,在创建新节点时,需要使用malloc为它们分配空间;一旦不再需要任何已 分配的空间,就应该使

    2024年02月09日
    浏览(45)
  • 算法:分治思想处理归并递归问题

    利用归并思想进行分治也是很重要的一种思路,在解决逆序对的问题上有很大的需求空间 于是首先归并排序是首先的,归并排序要能写出来: 以上为归并排序基本算法原理,基于这个原理可以解决逆序对问题,逆序对问题通常问法是,给定某一个数据,在整个数组中找比这

    2024年02月10日
    浏览(43)
  • 分治法解二维的最近对问题,算法分析与代码实现,蛮力法与分治法解决二维的最近对问题的区别

    🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 -  数据结构与算法_勾栏听曲_0 🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️ 📌个人主

    2024年02月04日
    浏览(43)
  • C++:分治算法之输油管道问题

    目录 描述 输入 输出 输入样例 输出样例 分析 代码 运行结果 ¢ 某石油公司计划建造一条 由东向西 的主输油管道。该管道要穿过一个有 n 口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。 ¢ 如果给定 n 口油井的位置,即它们的 x 坐标(

    2024年02月02日
    浏览(42)
  • 多数问题求解之蒙特卡洛与分治法

    多数问题(Majority Problem)是一个有多种求解方法的经典问题,其问题定义如下: 给定一个大小为 n n n 的数组,找出其中出现次数超过 n / 2 n/2 n /2 的元素 例如:当输入数组为 [ 5 , 3 , 5 , 2 , 3 , 5 , 5 ] [5, 3, 5, 2, 3, 5, 5] [ 5 , 3 , 5 , 2 , 3 , 5 , 5 ] ,则 5 5 5 是多数(majority)。 本文将

    2024年03月14日
    浏览(47)
  • 整数因子分解问题(分治法&&欧拉线性筛素数)

    问题描述: 大于1 的正整数n 可以分解为:n=x1*x2*…*xm。 例如,当n=12 时,共有8 种不同的分解式: 12=12; 12=6*2; 12=4*3; 12=3*4; 12=3*2*2; 12=2*6; 12=2*3*2; 12=2*2*3 。 编程任务: 对于给定的正整数n,编程计算n 共有多少种不同的分解式。 数据输入: 由文件input.txt 给出输入数据

    2024年01月17日
    浏览(43)
  • 【算法设计与分析】分治法(最近点对问题)

    目录 实验目的 实验内容与结果 蛮力法求解 分治法求解 实验总结 (1)掌握分治法思想。 (2)学会最近点对问题求解方法。 算法过程: 遍历n个点与剩余n-1个点之间的距离,在计算点对距离时不断更新最短距离的值,遍历完所有点对后即可求得最短点对距离。 伪代码: 复

    2024年02月08日
    浏览(48)
  • 【算法】减治法详解

    分治法是将一个大问题划分为若干个子问题,分别求解后将子问题的解进行合并得到原问题的解。减治法同样是讲一个大问题划分为若干个小的子问题,但是这些子问题不需要分别求解,只需要求解其中一个子问题便可,因此也不需要对子问题进行合并,可以说,减治法是一

    2024年02月04日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包