棋盘覆盖(C语言)
问题描述:
如何应用分治法求解棋盘覆盖问题呢?分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。k>0时,可将2k×2k的棋盘划分为4个2(k-1)×2(k-1)的子棋盘,如图(a)所示。这样划分后,由于原棋盘只有一个特殊方格,所以,这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求解,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如图(b)所示,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略,直至将棋盘分割为1×1的子棋盘。
思路:
如何应用分治法求解棋盘覆盖问题呢?分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。k>0时,可将2k×2k的棋盘划分为4个2(k-1)×2(k-1)的子棋盘,这样划分后,由于原棋盘只有一个特殊方格,所以,这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求解,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略,直至将棋盘分割为1×1的子棋盘。——来自百度百科
下面我来说说我的理解吧:
首先,我们按照最小的模式,也就是 k=0 的时候,此时只有一个特殊方格没有三角方格需要放置,当然这种情况还是比较少的。
接下来,就是 k=1 的时候,也就是有四个方格,无论特殊方格的位置在哪,我们都可以找到一个直角方格放置。
…
接下来,就是 k 不断地递增,利用分治的思想,可以把大方格划分成小方格,划分到最后就剩下最后一个包含有特殊方格的四方格,这个时候,我们的直角方格该以哪种形式存在呢?对吧,面临的四边其实都是可以放置直角方格的。
这个时候利用分治的思想,也就是说把原有的大方个,划分成四个相对小一个阶级的方格
…
到最后就回到了递归的出口,也就是说,特殊方格分别在四方格的四个角上的情况。
#include<stdio.h>
#define n 8 //n为2^k
int tr,tc; //子棋盘的左上角第一个方格的横纵坐标
int dr,dc; //特殊方格的横纵坐标
int size;
int board[n][n];
int tile=1; //骨牌序号从1开始
void input()
{
printf("输出棋盘长度:%d\n"