什么是棋盘覆盖方法?
我去找其他人的解释,恰恰发现一个矛盾的地方,就是看解释比较难理解,但是看解决棋盘覆盖的过程,就很容易理解什么是棋盘覆盖问题了。所以这里就不解释了,直接给一个解决16*16的棋盘解决过程,看完过程,相信你也理解了什么是棋盘问题了。
如下:
首先给出一个包含一个奇异点的16*16棋盘:
第一步是将该棋盘分为四个等大的子棋盘:
然后将该棋盘看做是4*4的棋盘,可以看到奇异点在左上角的子棋盘中,那么这一步的任务就是用一个(真的是一个)L型的棋子(下图中红色的格子)将其他三个子棋盘构造成含奇异点的子棋盘:
下一步是将红线分割的子棋盘又切割成四个子棋盘(白色线切开的子棋盘):
然后对每个红色线包围在里面的子棋盘,用一个L型棋子(黄色)又构造出奇异点,使得每个子棋盘都有一个奇异点,即白色线围起来的格子看做是一个整体,里面包含一个黄色的奇异点:
下一步是继续讲白色线包围的格子切分为4个子棋盘,这里为了方便观察,将前面所有的分割线去掉:
同理,对黄色的棋盘构造含奇异点的子棋盘(蓝色):
最后可以分割到2*2的格子,然后每个2*2的子棋盘都已经包含一个奇异点了,剩下的就是用L型旗子去填好剩下的三个格子。
(填充时,最好从左到右)
本文转载自:https://blog.csdn.net/qq_30268545/java/article/details/80600064
附上原创 算法实现代码(java)
public class QiPanFuGai {
public static void main(String[] args) {
int xlen = 16;
int ylen = 16;
int targetX = 5;
int targetY = 5;
int x[][] = new int[xlen][ylen];
x[targetX][targetY] = 2;
prinX(x);
System.out.println();
f(x,targetX,targetY,xlen,ylen,0,0);
prinX(x);
}
static void f(int [][]x ,int xx,int yy,int xlen,int ylen,int lx,int ly){
if(xlen<=2){
return;
}
System.out.println("xlen: "+xlen+" ylen: "+ylen);
System.out.println("lx: "+lx+" ly: "+ly);
System.out.println("xx: "+xx+" yy: "+yy);
int mx = lx+(xlen)/2-1;
int my = ly+(ylen)/2-1;
int k = 2;
System.out.println("mx: "+mx+" my: "+my);
if(xx<=mx){
//左上
if(yy<=my){
System.out.println("左上");
x[mx+1][my]=k;
x[mx+1][my+1]=k;
x[mx][my+1]=k;
prinX(x);
System.out.println();
//当前 奇异点 左上
f(x,xx,yy,xlen/2,ylen/2,lx,ly);
//中点下方 奇异点 左下
f(x,mx+1,my,xlen/2,ylen/2,lx+xlen/2,ly);
//中点右方 奇异点 右上
f(x,mx,my+1,xlen/2,ylen/2,lx,ly+ylen/2);
//中点右下方 奇异点 右下
f(x,mx+1,my+1,xlen/2,ylen/2,lx+xlen/2,ly+ylen/2);
}
//右上
else {
System.out.println("右上");
x[mx][my]=k;
x[mx+1][my]=k;
x[mx+1][my+1]=k;
prinX(x);
System.out.println();
//当前 奇异点 右上
f(x,xx,yy,xlen/2,ylen/2,lx,ly+ylen/2);
//中点下方 奇异点 左下
f(x,mx+1,my,xlen/2,ylen/2,lx+xlen/2,ly);
//中点 奇异点 左上
f(x,mx,my,xlen/2,ylen/2,lx,ly);
//中点右下方 奇异点 右下
f(x,mx+1,my+1,xlen/2,ylen/2,lx+xlen/2,ly+ylen/2);
}
}else {
//左下
if(yy<=my){
System.out.println("左下");
x[mx][my]=k;
x[mx][my+1]=k;
x[mx+1][my+1]=k;
prinX(x);
System.out.println();
//当前奇异点 左下
f(x,xx,yy,xlen/2,ylen/2,lx+xlen/2,ly);
//中点 奇异点 左上
f(x,mx,my,xlen/2,ylen/2,lx,ly);
// 奇异点 右上
f(x,mx,my+1,xlen/2,ylen/2,lx,ly+ylen/2);
//中点右下方 奇异点 右下
f(x,mx+1,my+1,xlen/2,ylen/2,lx+xlen/2,ly+ylen/2);
}
//右下
else {
System.out.println("");
x[mx][my]=k;
x[mx+1][my]=k;
x[mx][my+1]=k;
prinX(x);
System.out.println();
//当前奇异点 右下
f(x,xx,yy,xlen/2,ylen/2,lx+xlen/2,ly+ylen/2);
//中点 奇异点 左上
f(x,mx,my,xlen/2,ylen/2,lx,ly);
//奇异点 右上
f(x,mx,my+1,xlen/2,ylen/2,lx,ly+ylen/2);
//中点下方 奇异点 左下
f(x,mx+1,my,xlen/2,ylen/2,lx+xlen/2,ly);
}
}
}
static void prinX(int x[][]){
for (int i = 0 ;i<x.length;i++){
for (int j = 0 ;j<x[0].length;j++){
System.out.print(x[i][j]+" ");
}
System.out.println();
}
}
}
输出结果:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 2 2 0 0 2 2 0 0 2 2 0 0 2 2 0
0 2 0 0 0 0 2 0 0 2 0 0 0 0 2 0
0 0 0 2 2 0 0 0 0 0 0 2 2 0 0 0
0 0 0 2 0 0 0 0 0 0 0 0 2 0 0 0
0 2 0 0 0 2 2 0 0 2 2 0 0 0 2 0
0 2 2 0 0 2 2 0 0 0 2 0 0 2 2 0
0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0
0 2 2 0 0 2 0 0 0 0 2 0 0 2 2 0
0 2 0 0 0 2 2 0 0 2 2 0 0 0 2 0
0 0 0 2 0 0 0 0 0 0 0 0 2 0 0 0
0 0 0 2 2 0 0 0 0 0 0 2 2 0 0 0
0 2 0 0 0 0 2 0 0 2 0 0 0 0 2 0
0 2 2 0 0 2 2 0 0 2 2 0 0 2 2 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0