Triomino拼图 || 棋盘覆盖问题 (分治法)

Triomino拼图是有一个2^k * 2^k (k>=1)个方格的棋盘,其中恰有一个方格残缺。下图给出了k=1时各种可能的Triomino拼图,其中残缺方格用空白表示。

这样的棋盘被称作“三格板”,Triomino拼图问题就是要用这种三格板覆盖更大的Triomino拼图。

要求:(1)两个三格板不能重叠;

        (2)三格板不能覆盖残缺方格,但必须覆盖其他所有方格。

问题分析:

Triomino 拼图问题是关于如何将一系列特定的L形拼图块排列进一个预定大小的矩形框架中,要求完全填充这个框架且没有剩余空间。

数学建模:

我们可以将拼图问题抽象为一个矩阵填充问题,其中每个L形拼图块需要被放置在矩阵的特定位置上,以满足全部拼图块都能完美拟合进矩阵的约束。该问题可以用一个二维数组表示,数组中的每个元素代表矩阵中的一个单元格,可以是空的或者被某个拼图块所占据。

算法设计:

首先把棋盘划分为四块,依次考虑左上,右上,左下,右下。如果缺陷位置在左上,则继续递归,再分划成四块,只到每块的大小为1,如果缺陷位置不在左上,则填充最右下的坐标,然后继续分划。另一种顺序是,先找到缺陷位置所在象限,然后再划分棋盘,再填充。

C语言代码如下:

#include<stdio.h>
#define N 100
int board[N][N];
int tile = 0;
void ChessBoard(int tr, int tc, int dr, int dc, int size);
int main() {
	int tx = 0, ty = 0, dx = 1, dy = 0;
	int n = 4;
	printf("请输入棋盘的规模(2^k):n=");
	scanf("%d", &n);
	printf("请输入缺陷处坐标(dx,dy)(从0开始):");
	scanf("%d %d", &dx, &dy);
	board[dx][ dy] = -1;
	ChessBoard(tx, ty, dx, dy, n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			printf("%4d", board[i][j]);
		}
		printf("\n\n");
	}
	putchar('\n'); 
	return 0;
}

void ChessBoard(int tx, int ty, int dx, int dy, int n) {
	if (n == 1) return;
	
	int t = tile++;//L型骨牌号
	int s = n / 2;//分割棋盘
	//覆盖左上角棋盘
	if (dx < tx + s && dy < ty + s) {//有特殊方格则继续划分
		ChessBoard(tx, ty, dx, dy, s);
	}
	else {//无特殊方格则先覆盖再划分
		board[tx + s - 1][ty + s - 1] = t;//覆盖右下角
		ChessBoard(tx, ty, tx + s - 1, ty + s - 1, s);
	}
	//覆盖右上角棋盘
	if (dx < tx + s && dy >= ty + s) {//有特殊方格则继续划分
		ChessBoard(tx, ty+s, dx, dy, s);
	}
	else {
		board[tx + s - 1][ty + s] = t;//覆盖左下角
		ChessBoard(tx, ty+s, tx + s - 1, ty + s, s);
	}
	//覆盖左下角棋盘
	if (dx >= tx + s && dy < ty + s) {//有特殊方格则继续划分
		ChessBoard(tx+s, ty, dx, dy, s);
	}
	else {
		board[tx + s ][ty + s - 1] = t;//覆盖右上角
		ChessBoard(tx +s, ty,tx+s, ty + s - 1, s);
	}
	//覆盖右下角棋盘
	if (dx >= tx + s && dy >= ty + s) {//有特殊方格则继续划分
		ChessBoard(tx+s, ty+s, dx, dy, s);
	}
	else {
		board[tx + s][ty + s] = t;//覆盖左上角
		ChessBoard(tx+s, ty + s, tx + s , ty + s, s);
	}
}

代码看不懂的可以去mooc看东北大学郭楠教授的算法设计与分析课,讲的很清楚,易懂。

相关推荐

  1. 二分图试炼之棋盘覆盖

    2024-06-11 10:58:02       17 阅读
  2. 分治构建Gray码问题

    2024-06-11 10:58:02       13 阅读
  3. 小程序分享携带参数,被覆盖问题

    2024-06-11 10:58:02       37 阅读
  4. 搜索算法练习——拼图问题

    2024-06-11 10:58:02       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-11 10:58:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-11 10:58:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-11 10:58:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-11 10:58:02       18 阅读

热门阅读

  1. 2024.6.10刷题记录

    2024-06-11 10:58:02       12 阅读
  2. 三分的空间至关重要

    2024-06-11 10:58:02       6 阅读
  3. 【烟花game】

    2024-06-11 10:58:02       10 阅读
  4. 【DevOps】什么是 pfSense?免费构建SDWAN

    2024-06-11 10:58:02       12 阅读
  5. MATLAB入门教程

    2024-06-11 10:58:02       10 阅读
  6. PHP的基础代码

    2024-06-11 10:58:02       9 阅读
  7. 等保必须做?不做等保行不行?

    2024-06-11 10:58:02       12 阅读
  8. 一些简单却精妙的算法

    2024-06-11 10:58:02       7 阅读
  9. MySQL-函数/约束

    2024-06-11 10:58:02       9 阅读