`

棋盘覆盖(递归分治问题)

阅读更多

 

在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。

 四各L型骨牌如下图1

 图1  


棋盘中的特殊方格如图2

图2

    实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。以上原理如图3所示。

图3

 


    将棋盘保存在一个二维数组中。骨牌号从1开始,特殊方格为0,如果是一个4 * 4的棋盘,特殊方格为(2,2),那么程序的输出为

 

2   2   3   3   
2   1   1   3   
4   1   0   5   
4   4   5   5
 
相同数字的为同一骨牌。

=============================================================================

 

package 递归与分治;


public class ChessboardCoverage {

	private int tile = 1; //L型骨牌的值
	private int Board[][] = new int[16][16]; //表示棋盘
	
	/*
	 * tr:棋盘左上角方格的行号 tc:棋盘左上角方格的列号 dr:特殊方格所在的行号 dc:特殊方格所在的列号 size:方形棋盘的边长
	 */
	private void coverageChessBoard(int tr, int tc, int dr, int dc, int size) {
		if (size == 1)
			return;
		int t = tile++, s = size / 2;

		// 覆盖左上角子棋盘
		if (dr < tr + s && dc < tc + s)
			// 特殊方格在此棋盘中
			coverageChessBoard(tr, tc, dr, dc, s);
		else // 此棋盘无特殊方格
		{
			// 用t号L型骨型牌覆盖左上角子棋盘的右下角
			Board[tr + s - 1][tc + s - 1] = t;
			// 覆盖左上角的其余方格
			coverageChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
		}

		// 覆盖右上角子棋盘
		if (dr < tr + s && dc >= tc + s)
			coverageChessBoard(tr, tc + s, dr, dc, s);
		else {
			// 用t号L型骨型牌覆盖右上角子棋盘的左下角
			Board[tr + s - 1][tc + s] = t;
			// 覆盖右上角的其余方格
			coverageChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
		}

		// 覆盖左下角子棋盘
		if (dr >= tr + s && dc < tc + s)
			coverageChessBoard(tr + s, tc, dr, dc, s);
		else {
			// 用t号L型骨型牌覆盖左下角子棋盘的右上角
			Board[tr + s][tc + s - 1] = t;
			// 覆盖左下角的其余方格
			coverageChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
		}

		// 覆盖右下角子棋盘
		if (dr >= tr + s && dc >= tc + s)
			coverageChessBoard(tr + s, tc + s, dr, dc, s);
		else {
			// 用t号L型骨型牌覆盖右下角子棋盘的左上角
			Board[tr + s][tc + s] = t;
			// 覆盖右下角的其余方格
			coverageChessBoard(tr + s, tc + s, tr + s, tc + s, s);
		}
	}

	private void displayBoard(int size) {
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++)
				System.out.printf("%4s", Board[i][j] + "");
			System.out.println();
		}
	}
	
	public static void main(String[] args) {
		ChessboardCoverage chessboardCoverage = new ChessboardCoverage();
		chessboardCoverage.coverageChessBoard(0, 0, 2, 2, 4);
		chessboardCoverage.displayBoard(4);
	}
}

 

 

 

分享到:
评论

相关推荐

    棋盘覆盖问题 分治法——C++代码

    总之,棋盘覆盖问题的分治法实现是一个很好的编程练习,它能够锻炼编程者的问题分解能力以及理解和应用递归解决问题的能力。通过分析和理解这段C++代码,学习者可以深入理解分治法的工作原理,并将其应用到其他类似...

    算法分析实习-棋盘覆盖(递归分治)

    在IT领域,算法是解决问题的关键工具,而"棋盘覆盖"问题是一个经典的计算机科学问题,它涉及到算法设计、递归思想以及分治策略的应用。在这个实习项目中,我们需要使用L型骨牌无重叠地覆盖一个n*n的棋盘,但有一个...

    Java基于分治算法实现的棋盘覆盖问题示例

    Java代码实现了基于分治算法的棋盘覆盖问题,使用递归函数来处理子棋盘,并使用数组来存储棋盘的状态。代码中使用了四个参数tr、tc、dr、dc分别表示棋盘的左上角行号、左上角列号、特殊方格的行号和特殊方格的列号。...

    棋盘覆盖问题实现

    通过对棋盘覆盖问题的研究和实现,我们不仅了解了递归分治的基本思想,还掌握了如何通过编程解决问题的具体步骤。此问题的解决思路可以应用于许多其他领域,如数据结构、图形学等,具有广泛的应用价值。

    棋盘覆盖问题-基于C++使用分治递归算法求解棋盘覆盖问题.zip

    棋盘覆盖问题 棋盘覆盖问题_基于C++使用分治递归算法求解棋盘覆盖问题

    棋盘覆盖算法 ,算法设计与分析,递归与分治策略

    在一个2的k次方乘以2的k次方个方格的棋盘中,恰有一个方格与其他方格不同为特殊方格,棋盘称为特殊棋盘,用4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

    棋盘覆盖问题 算法设计

    对于棋盘覆盖问题而言,可以将大的棋盘分割成四个子棋盘,然后递归地解决每个子棋盘中的覆盖问题。 #### 三、算法实现细节 1. **初始化**: - 定义一个二维数组 `board` 来表示棋盘。 - 使用变量 `tile` 来追踪...

    用 分治法 解决棋盘覆盖问题

    棋盘覆盖问题是计算机科学领域中一个经典的分治问题实例。通过对大问题的逐步分解,最终解决了看似复杂的问题。本篇文章通过详细的解释和示例代码,帮助读者理解了如何使用分治法解决棋盘覆盖问题。通过递归的方法,...

    算法设计与分析(用分治法求解棋盘覆盖问题)

    **算法设计与分析——棋盘覆盖问题的分治法求解** 在计算机科学中,算法设计与分析是核心部分,它涉及到如何有效地解决问题并优化计算效率。本篇将重点探讨如何利用分治策略来解决棋盘覆盖问题。棋盘覆盖问题是一个...

    棋盘覆盖算法(分治算法)

    ### 棋盘覆盖算法(分治算法) #### 背景与定义 在计算机科学领域,特别是算法设计中,“棋盘覆盖”问题是一个经典的题目,它涉及到如何使用...此外,这种方法还可以推广到其他类型的分治问题上,具有一定的普遍意义。

    分治法解决棋盘覆盖

    这个过程就像是在解决一个大棋盘覆盖问题时,我们先将其拆分成小棋盘的覆盖问题,然后逐步解决。 棋盘覆盖问题是一个经典的分治法应用实例。通常,这个问题被描述为:给定一个n×n的棋盘,如何用最少数量的皇后(或...

    MFC界面实现分治法解决棋盘覆盖算法的演示

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 库来实现一个界面,以演示通过分治法解决棋盘覆盖问题。MFC 是 Microsoft 提供的一个C++类库,它为开发者提供了一种构建Windows应用程序的框架,...

    棋盘覆盖问题(c#图形界面)

    棋盘覆盖问题是一个经典的计算机科学问题,涉及到递归分治策略和算法设计。在这个问题中,目标是找到一种方法来用最少数量的棋子(通常是皇后或国王)覆盖一个棋盘的一部分,使得没有任何两个棋子位于同一行、同一列...

    递归与分治策略及其应用

    对于特殊棋盘覆盖问题,递归地应用分治策略,我们可以先解决边界情况,比如1×n或m×1的棋盘,然后处理一般情况。在每一步中,我们需要考虑如何放置L型骨牌,使得覆盖尽可能多的空格,同时保持子棋盘的划分。这需要...

    算法分治 汉诺塔、棋盘覆盖 JAVA图形演示

    这也是一个典型的分治问题,可以通过回溯法来解决。在Java中,我们可以创建一个二维数组表示棋盘,然后使用递归尝试在每个位置放置皇后,并检查是否与已放置的皇后冲突。如果找到解决方案,则返回成功;否则,回溯到...

    棋盘覆盖问题

    在这里,我们将深入探讨棋盘覆盖问题的递归分治策略。 首先,让我们明确棋盘覆盖问题的基本概念。想象一个标准的国际象棋棋盘,由黑白相间的正方形格子组成。问题的目标是找到一种方式来覆盖棋盘的一部分或全部,...

    使用分治递归来求解棋盘覆盖问题.zip

    通过这种方法,我们可以在棋盘覆盖问题上有效地应用分治递归策略。这个方法不仅适用于8x8棋盘,也可以扩展到其他大小的棋盘,只要棋盘大小能够被2整除。通过递归地解决子问题,我们能够以指数级的时间复杂度找到可能...

    分治法-棋盘覆盖 java

    ### 分治法与棋盘覆盖问题 #### 一、引言 在计算机科学领域,算法设计是解决问题的关键技术之一。其中,“分治法”是一种重要的算法设计思想,它通过将一个大问题分解成若干个规模较小但结构相同的小问题来解决...

    西南交通大学算法分析与设计实验报告 - 棋盘覆盖问题.docx

    3. 对每个子问题递归调用棋盘覆盖函数,直到子棋盘大小为1,结束递归。 4. 将所有子问题的解合并,形成整个棋盘的覆盖方案。 复杂度分析: 每次划分后产生4个大小减半的子问题,因此时间复杂度可表示为O(n) = 4 * O...

    JAVA实现棋盘覆盖问题

    ### JAVA 实现棋盘覆盖问题 #### 知识点概览 ...通过上述分析可以看出,该程序成功实现了棋盘覆盖问题的解决方案,并利用了分治法的思想,借助Java语言的基础语法完成了一个实用而有趣的递归算法实现。

Global site tag (gtag.js) - Google Analytics