棋盘覆盖问题——分治法
  SVztbiW9p18f 2023年11月01日 93 0

问题描述

有一个 2^kx<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);
    }
}

参考资料:《计算机算法设计与分析(第四版)》  

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jTMfQq5cr55P   2024年05月17日   44   0   0 算法与数据结构
  jTMfQq5cr55P   2024年05月17日   40   0   0 算法与数据结构
SVztbiW9p18f
作者其他文章 更多