【计算机算法设计与分析】棋盘覆盖问题(C++_分治法)

文章目录

题目描述

在一个 2 k × 2 k 2^k \times 2^k 2k×2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一个特殊方格,且称该棋盘为一个特殊棋盘。显然,特殊方格在棋盘上出现的位置有 4 k 4^k 4k 种情况,即k>=0,有 4 k 4^k 4k种不同的特殊棋盘。

棋盘覆盖:用4种不同形态(方向不同)的L型骨牌覆盖一个给定的特殊棋盘(即特殊方格的位置已经确定了)上除特殊方格外的所有方格,且任何两个L型骨牌不得重复覆盖。

问题要求输入棋盘的边长n,以及特殊方格的坐标。输出覆盖后的棋盘。

测试样例

输入:

4

1 0

输出:

3 3 4 4

1 3 2 4

6 2 2 5

6 6 5 5

算法原理

通常用分治法解决一维问题时,我们将一维数轴划分为数段,解决二维问题时就需要把二维空间均匀分成四块,对每一块继续递归。

对于这个问题,我们将棋盘划分为左上、右上、左下、右下四部分,对于每一部分判断特殊方格是否在其中。若特殊方格在这部分棋盘中,就直接将其继续作为一个子问题递归解决;若不在,则填充一个特殊方格,将其改变成一个更小的特殊棋盘(子问题),依次递归解决。按照这样来算,对于当前的整个棋盘的四部分来说,有特殊方格那部分不用覆盖,而其余三部分都新增了一个特殊方格,恰好凑成一个L型骨牌,递归直到当前棋盘只有一个方格为止。如下所示:

算法实现

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
static int n, g[100][100], num = 1;

void chessBoard(int x, int y, int sx, int sy, int size) {
	if (size == 1)
		return;
	int s = size / 2, t = num++;
	if (sx < x + s && sy < y + s)  chessBoard(x, y, sx, sy, s);//特殊方格在左上角
	else {//特殊方格不在左上角
		g[x + s - 1][y + s-1] = t;//左上角棋盘的右下角
		chessBoard(x, y, x + s - 1, y + s - 1, s);
	}
	if (sx < x + s && sy >= y + s)  chessBoard(x, y + s, sx, sy, s);//特殊方格在右上角
	else {  //特殊方格不在右上角
		g[x + s - 1][y + s] = t;//右上角棋盘的左下角
		chessBoard(x, y + s, x + s - 1, y + s, s);
	}
	if (sx >= x + s && sy >= y + s)  chessBoard(x + s, y + s, sx, sy, s);//特殊方格在右下角
	else {  //特殊方格不在右下角
		g[x + s][y + s] = t;//右下角棋盘的左上角
		chessBoard(x + s, y + s, x + s, y + s, s);
	}
	if (sx >= x + s && sy < y + s)  chessBoard(x + s, y, sx, sy, s);//特殊方格在左下角
	else {  //特殊方格不在左下角
		g[x + s][y + s-1] = t;//左下角棋盘的右上角
		chessBoard(x + s, y, x + s, y + s-1, s);
	}
}

void main() {
	int x, y;//特殊方格坐标
	cin >> n;
	cin >> x >> y;
	g[x][y] = num;
	chessBoard(0, 0, x, y, n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			cout << g[i][j] << "\t";
		cout << endl;
	}
}

参考资料

【算法】棋盘覆盖详解,基础教程~

相关推荐
江南十四行16 小时前
并发编程(二)
java·开发语言
weixin_4713830316 小时前
统一缩放单位基础(px、em、rem)
开发语言·javascript·ecmascript
yqcoder16 小时前
数据劫持的双雄:深入解析 Object.defineProperty 与 Proxy
开发语言·前端·javascript
咩咦17 小时前
C++学习笔记20:日期类比较运算符重载
c++·学习笔记·类和对象·运算符重载·比较运算符·日期类
qingfeng1541517 小时前
企业微信 API 自动化开发指南:从消息回调到智能运营实战
java·开发语言·python·自动化·企业微信
凌波粒17 小时前
LeetCode--404.左叶子之和(二叉树)
算法·leetcode·职场和发展
paeamecium17 小时前
【PAT甲级真题】- A+B in Hogwarts
c++·算法·pat考试·pat
jonyleek17 小时前
性能就是生命线?规则引擎如何支撑实时决策
java·开发语言·数据库
青山师17 小时前
二叉树与BST深度解析:遍历算法与平衡策略
数据结构·算法·面试·二叉树·算法与数据结构·java面试·数据结构与算法分析