棋盘覆盖问题(保姆级解释)
作者:互联网
这可是保姆级解释哦!
1、问题描述:
在一个个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。棋盘覆盖问题要求用如图所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
2、问题分析过程:
① 显然,用户输入k的值(k必须为自然数),然后再输入特殊方格的坐标(坐标的格式会在下面提到),这样便可以确定一个带有一个特殊方格的的棋盘(尚未被覆盖),接下来交由计算机使用上图四种L型骨牌进行覆盖操作。这种覆盖操作具体的形式是什么呢?
② 可以用一个二维数组chessBoard来表示这个的棋盘,该二维数组规模为,每个棋盘的方格用chessBoard[i][j]来表示
但是用户认为一个棋盘最左上角的方格坐标应该为而不是,这点需要注意。当用户指定并输入特殊方格的坐标为时,代表着chessBoard[1][2] = 特殊方格对应的值。
③ (1)为了找到覆盖操作的规律,假设用户输入的,即创建一个的棋盘,然后用户输入特殊方格的坐标为,则chessBoard[1][2]填充为黑色,如图1-1所示:(为便于编程,接下来这个用户输入的特殊方格都用表示)
图1-1
(2) 将这个棋盘均等分为4个子棋盘,可以发现特殊方格位于左上角子棋盘中,于是将“右上角子棋盘”的“”(这个坐标是相对于该子棋盘而言的,后面的描述也类似)和“右下角子棋盘”的“”和“左下角子棋盘”的“”设置(覆盖)为新的特殊方格,如图1-2:
图1-2
为什么要设置这种新的特殊方格呢?其实是为“递归覆盖”服务的。可以发现这三个新的特殊方格刚好对应于骨牌(称为缺左上骨牌):
设置这三个新的特殊方格相当于用缺左上骨牌覆盖了棋盘的相应位置。
(3) 接下来对4个子棋盘各自进行覆盖操作,就是“将本问题分解为4个子问题,再分别解决这4个子问题,解决完后,本问题就解决”,这正体现了分治思想。子问题和本问题是同一类型的不同输入规模的问题,如果用户当初输入的k值为2而不是3,那么需要覆盖操作的自然就是棋盘了,正对应于上述的子棋盘,只是假设用户对每个棋盘输入的特殊方格的坐标分别为罢了(注意是用户输入!)
(4) 解决对左上角子棋盘进行覆盖操作这个子问题时,同样需要再将该子棋盘均等分为4个的子子棋盘,由于特殊方格位于右上角子子棋盘中,所以将“左上角2×2子子棋盘”的“”(这个坐标是相对于该子棋盘而言的,后面的描述也类似)和“右下角子子棋盘”的“”和“左下角子子棋盘”的“”设置(覆盖)为新的特殊方格,如图1-3:
图1-3
可以发现这三个新的特殊方格刚好对应于骨牌(称为缺右上骨牌):
(5) 解决对右上角子子棋盘进行覆盖操作这个子子问题时,同样需要再将该子棋盘均等分为4个的子子子棋盘,这时每个子子子棋盘就是一个方格。由于特殊方格位于左下角方格,所以将左上角方格和右上角方格和右下角方格设置(覆盖)为新的特殊方格,如图1-4:
图1-4
可以发现这三个新的特殊方格刚好对应于骨牌(称为缺左下骨牌):
(6) 解决了所有的子子问题,就相当于解决了所有的子问题,就相当于解决了本问题,于是,棋盘覆盖问题迎刃而解,主要使用了分治思想。
④ 接下来就是根据上述解决问题的过程来编写程序,使用递归函数(Java中称为递归方法)是必不可少的。编写程序的过程不在这里描述,程序中已包含详细清晰的注释。
我认为我的程序比较冗余,不拿出来贻笑大方了,建议读者自己写写,如果真的想要俺的Java代码,可以给我发消息。
3、实现方式:
使用Java语言,在Intellij Idea上实现了该问题的解决。
4、测试运行结果:
本程序设有输入检查,在这里不演示。
标签:特殊,覆盖,保姆,方格,骨牌,棋盘,输入 来源: https://blog.csdn.net/qq_25245727/article/details/121096192