棋盘覆盖(JAVA)

问题:用4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
在这里插入图片描述
思路:应用分治法
分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。
k>0 时,可将2k×2k的棋盘划分为4个2(k-1)×2(k-1)的子棋盘,如图4.11(a)所示。这样划分后,由于原棋盘只有一个特殊方格,所 以,
这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求 解,
可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略, 直至将棋盘分割为1×1的子棋盘。

package section2.Divide_and_Conquer;
import java.util.Scanner;
public class ChessboardCoverage {
	public static void main(String[] args) {
		int size = 4; // 棋盘的长,固定为4
		int dr = 1; // 特殊棋子所在的行
		int dc = 1; // 特殊棋子所在的列
		ChessboardCoverage c = new ChessboardCoverage();
		c.chessBoard(0, 0, dr, dc, size);
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				System.out.print(board[i][j] + "  ");
			}
			System.out.println();
		}

	}

	int title = 1; // 表示L型骨牌的编号
	static int[][] board = new int[4][4];

	// 处理带有特殊棋子的棋盘.tr、tc表示棋盘的入口即左上角的行列号,dr、dc表示特殊棋子的行列位置,size表示棋盘的行数或者列数
	public void chessBoard(int tr, int tc, int dr, int dc, int size) {
		if (size == 1) return;
		int t = title++; // 骨牌编号
		System.out.println(t);
		int s = size / 2;// 每一次化大棋盘为一半的子棋盘
		// 要处理带有特殊棋子的棋盘,第一步先处理左上棋盘(后面三步与此步重复)
		if (dr < tr + s && dc < tc + s)// 左上角子棋盘有特殊棋子
			chessBoard(tr, tc, dr, dc, s);// 处理有特殊棋子的左上角子棋盘
		else// 处理无特殊棋子的左上角子棋盘
		{
			board[tr + s - 1][tc + s - 1] = t;// 设左上角子棋盘的右下角为特殊棋子,用t型的骨牌覆盖。由于骨牌有三种,当处理过程中同一级设置的特殊棋子用相同的骨牌覆盖
			chessBoard(tr, tc, tr + s - 1, tc + s - 1, s);// 处理有用骨牌覆盖的格子作为特殊棋子的左上角子棋盘
		}
		// 第二步处理右上角棋盘
		if (dr < tr + s && dc >= tc + s)// 右上角子棋盘有特殊棋子
		{
			chessBoard(tr, tc + s, dr, dc, s);// 处理有特殊棋子的右上角子棋盘
		} else {
			board[tr + s - 1][tc + s] = t;// 设右上角子棋盘的左下角为特殊棋子,用t型的骨牌覆盖。由于骨牌有三种,当处理过程中同一级设置的特殊棋子用相同的骨牌覆盖
			chessBoard(tr, tc + s, tr + s - 1, tc + s, s);// 处理有用骨牌覆盖的格子作为特殊棋子的右上角子棋盘
		}
		// 第三步处理左下角子棋盘
		if (dr >= tr + s && dc < tc + s)// 左下角子棋盘有特殊棋子
		{
			chessBoard(tr + s, tc, dr, dc, s);// 处理有特殊棋子的左下角子棋盘
		} else {
			board[tr + s][tc + s - 1] = t;// 设左下角子棋盘的右上角为特殊棋子,用t型的骨牌覆盖。由于骨牌有三种,当处理过程中同一级设置的特殊棋子用相同的骨牌覆盖
			chessBoard(tr + s, tc, tr + s, tc + s - 1, s);// 处理有用骨牌覆盖的格子作为特殊棋子的左下角子棋盘
		}
		// 第四步处理右下角棋盘
		if (dr >= tr + s && dc >= tc + s)// 右下角子棋盘有特殊棋子
		{
			chessBoard(tr + s, tc + s, dr, dc, s);// 处理有特殊棋子的右下角子棋盘
		} else {
			board[tr + s][tc + s] = t;// 设子棋盘右下角的左上角为特殊棋子,用t型的骨牌覆盖。由于骨牌有三种,当处理过程中同一级设置的特殊棋子用相同的骨牌覆盖
			chessBoard(tr + s, tc + s, tr + s, tc + s, s);// 处理有用骨牌覆盖的格子作为特殊棋子的右下角子棋盘
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值