棋盘覆盖问题[算法设计与分析]

实验问题:

用缺了一个格子的正方形去覆盖一个n*n的棋盘,问需要多少个才能覆盖全部棋盘

问题分析:

第一步:可以将棋盘平分为4个象限,然后判定残缺位置落在哪个象限内。

第二步:去填充中间的四个方块中的三个,残缺位置所处的象限的方块不填充。那么问题就转化为四个相同性质的子问题

第三步:顺序处理四个象限,递归实现

数学建模:

建立函数Triomino(r,c,i,j,n) 其中(r,c)是每个象限第一个点,(i,j)是残缺点的坐标,n是棋盘的规模。

第一步:找一个基准格子坐标(n/2,n/2)

判断残缺位置坐标:(i,j)与(r+n/2,c+n/2)关系确定残缺位置所处的象限。

第二步:覆盖中间四个格子中的三个。

第三步:递归顺序处理四个象限,递归出口时棋盘规模小于2

实验代码:

//棋盘覆盖问题
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<iostream>

using namespace std;

int amo = 0;
int a[100][100] = {0};

using namespace std;

void Triomino(int r,int c,int i, int j, int n) {
	int set = 0;
	if (n < 2) {
		return;
	}
	amo += 1;
	set = amo;
	//划分
	//找到一个基准格子
	int p = n / 2;
	//填充数
	//判断缺省位置在划分区域哪个位置并覆盖中心
	//第一象限
	if (i < r + p && j < c + p) {
		//先覆盖给定的缺陷
		a[r + p - 1][c + p] = set;
		a[r + p][c + p - 1] = set;
		a[r + p][c + p] = set;
		Triomino(r, c, i, j, p);
		Triomino(r, c + p, r + p - 1, c + p, p);
		Triomino(r + p, c, r + p, c + p - 1, p);
		Triomino(r + p, c + p, r + p, c + p, p);
	}
	//第二象限
	else if (i < r + p && j >= c + p) {
		a[r + p - 1][c + p - 1] = set;
		a[r + p][c + p - 1] = set;
		a[r + p][c + p] = set;
		Triomino(r, c + p, i, j, p);
		Triomino(r, c, r + p - 1, c + p - 1, p);
		Triomino(r + p, c, r + p, c + p - 1, p);
		Triomino(r + p, c + p, r + p, c + p, p);
	}
	//第三象限
	else if (i >= r + p && j < c+p) {
		a[r + p - 1][c + p - 1] = set;
		a[r + p - 1][c + p] = set;
		a[r + p][c + p] = set;
		Triomino(r + p, c, i, j, p);
		Triomino(r, c, r + p - 1, c + p - 1, p);
		Triomino(r, c + p, r + p - 1, c + p, p);
		Triomino(r + p, c + p, r + p, c + p, p);
	}
	//第四象限
	else if(i>=r+p&&j>=c+p){
		a[r + p - 1][c + p - 1] = set;
		a[r + p][c + p - 1] = set;
		a[r + p - 1][c + p] = set;
		Triomino(r + p, c + p, i, j, p);
		Triomino(r, c, r + p - 1, c + p - 1,p);
		Triomino(r, c + p, r + p, c + p - 1,p);
		Triomino(r + p, c, r + p - 1, c + p,p);
	}
}

void print(int n) {
	int i = 0;
	int j = 0;
	for (i = 0;i < n;i++) {
		for (j = 0;j < n;j++) {
			cout << a[i][j] << "\t";
		}
		cout << '\n';
	}
}

int main() {
	int n = 0;
	int i = 0;
	int j = 0;
	cout << "请输入棋盘规模大小:";
	cin >> n;
	cout << "请输入初始棋盘残缺位置坐标:" ;
	cin >> i >> j;
	Triomino(0, 0, i, j, n);
	cout << "填充结果:" << endl;
	print(n);
	system("pause");
	return 0;
}

实验结果:

<数字代表覆盖的顺序>

时间复杂度分析: 

当k=0时T(k)=O(1)

当k>0时T(k)=4T(k-1)+O(1)即四个象限以及中间四个格子的覆盖

时间复杂度为O(

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

粒粒米z

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

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

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

打赏作者

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

抵扣说明:

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

余额充值