- 1、本文档共24页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
[算法合集之浅谈棋盘的分割思想
棋盘中的棋盘
——浅谈棋盘的分割思想
复旦大学附属中学 俞鑫
【摘要】【关键词】——棋盘的分割思想。
对于一个m×n的棋盘,它所含的子棋盘共有Cm×Cn个,而其分割方法更是不计其数。巧妙地对棋盘进行分割,可以解决许多种类的棋盘问题。
例一:棋盘覆盖(经典问题)
题目描述:
在一个2k×2k方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一特殊棋盘。显然特殊方格在棋盘上出现的位置有4k种情形。因而对任何k≥0,有4k种不同的特殊棋盘。图中的特殊棋盘是当k=2时16个特殊棋盘中的一个。
在棋盘覆盖问题中,我们要用以下4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。易知,在任何一个2k×2k的棋盘覆盖中,用道的L型骨牌个数恰为(4k-1)/3。
现求一种覆盖方法。
输入:第一行为k(棋盘的尺寸),第二行为x,y (1 ≤ x,y ≤ 2k ) ,分别表示特殊方格所在行与列。
输出:共2k行,每行2k个数,分别表示覆盖该格的L型的编号(特殊格用0表示)。
样例:
输入:
2
1 2
输出:
1 0 2 2
1 1 3 2
4 3 3 5
4 4 5 5
算法分析
由棋盘尺寸为2k×2k ,我们可以想到将其分割成四个尺寸为2k-1×2k-1的子棋盘
可是,由于含特殊方格的子棋盘与其它子棋盘不同,问题还是没有解决。
只要稍作思考,我们就可以发现,只要将L型如图放置在棋盘的中央,就可以使四个子棋盘都变成特殊棋盘。此时问题也变成了四个相同的子问题,只需运用简单的递归就可以解决这道问题了。
二位数组num: 覆盖该格的L型的编号,下文所说的
对方格赋值即对其对应的num赋值。
x1,y1: 当前棋盘左上角方格的行号与列号
x2,y2: 当前棋盘右下角方格的行号与列号
x3,y3: 当前棋盘中特殊格的行号与列号
ck: 当前棋盘的尺寸( 2ck×2ck )
cnum: 当前L型骨牌的编号
初始值:
开始时,将num[x,y]设为0
当ck=0时:棋盘尺寸为1×1,该格为已赋值的特殊格,不进行任何操作。
当ck0时:设xm为(x1+x2+1)/2,ym为(y1+y2+1)/2,比较x3与xm,y3与ym的大小就能知道特殊格所在子棋盘的位置,将另外三个子棋盘中靠近棋盘中央的三个方格赋值为cnum,并分别作为这三个子棋盘的特殊格。随后cnum增加1。再对这四个棋盘分别进行递归处理。
复杂度分析
时间复杂度:O(4k )
空间复杂度:O(4k )
由于覆盖一个2k×2k棋盘所需的L型骨牌个数为 (4k –1)/3,故该算法是一个在渐进意义下最优的算法。
参考程序
GAMERS.PAS
小结
将棋盘分割成子棋盘,要遵循以下两点:
1.分割出的棋盘要与原棋盘尽可能相像。
2.将原棋盘分割后尽量不要留下剩余部分。
但如果分割后必定留下剩余部分又该如何呢?
下面这道例题就是用来解答这个问题的。
例二:孔明棋问题(URAL1051)
题目描述:
在一个无限大的棋盘的节点上有一些棋子,这些棋子构成一个m×n的矩形(m为高度,n为宽度且1≤m,n≤1000)。你可以用一个棋子跳过另一个相邻的棋子,被跳过的棋子将被移去,请你求出最少能剩下几个棋子。
输入:m,n
输出:最少能剩下的棋子数
样例:
输入:
3 4
输出:
2
下面是一种走法:
算法分析
由于m=1或n=1的情况比较特殊,我们先处理m,n≥2的情况。为了叙述方便,我们称由棋子所在格子组成的棋盘为“真棋盘”。通过样例,我们可以发现,对于图(a)中位于4、5、6格的连续三个棋子,若第1、2、3格上无棋子而第7、8、9格上均有棋子的话,则可以通过图(b)的操作将这三个棋子移去。我们称4、5、6三颗棋子为模块1。
但是经过一些尝试后,我们发现只使用模块1对m×n的真棋盘进行分割效果并不理想。原因在于模块1每次对连续3行同时进行处理,当m不是3的倍数时,分割后总会留下剩余部分。(必须注意的是,图中用蓝框框起来的部分,必须等到其左边的棋子被去除后,才能成为模块1。)
因此,我们需要对剩余部分进行处理。
我们发现,当m不为3的倍数时,总是留下1行或2行剩余部分。由于1行棋子很难去除,当只留下1行时,因为m≥2,且m模3余1,故m至少为4。于是我们就将最上方4行都作为剩余部分,对于剩下的m-4行,由于m-4是3的倍数,这m-4行可以用模块1进行分割。而4行棋子又可分为两部分,每部分都是2行棋子。因此,处
文档评论(0)