Tromino是一个由期盼上的三个邻接方块组成的L型瓦片。我们的问题是,如何用Tromino覆盖少了一个方块(可以在棋盘上的任何位置)的2^2n*2^2n棋盘,除了这个缺失的方块,Tromino应该覆盖棋盘上的所有方块。而且不能有重叠。
这题基本思路是分治法,将问题化为多个相同规模的更小问题,可将原题目区域四等分,然后将3个没有缺方块的区域用L型瓦片覆盖,以产生4个相同的缺一方块棋盘。直至产生2*2方块,即可
import java.util.Scanner;
/**
* Tromino谜题,在(2^n)*(2^n)格内,有一个已经涂了的格子
* 现需用3个格子填满改表格,该图形为L型,并且不能重叠
*
*/
public class Tromino {
static int t = 0;
static int[][] blo;
static int randx =-1;
static int randy =-1;
public static void main(String[] args) {
System.out.print("请输入数量n,生成的格子为:(2^n)*(2^n)格:");
@SuppressWarnings("resource")
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int len = (int) Math.pow(2, n);
blo = new int[len][len];
for(int i=0; i<blo.length; i++){
for(int j = 0; j<blo[i].length; j++){
blo[i][j]=-1;
}
}
//生成随机的初始位置
randx = (int) (Math.random()*len);
randy = (int) (Math.random()*len);
blo[randx][randy] = 0;
show(blo);
handle(0,0,len);
String ans;
do{
System.out.println("输入ans将会显示答案:");
ans = in.next();
}while (!ans.equals("ans") );
System.out.println("=============ans=============");
show(blo);
}
//展示格子
public static void show(int[][] a){
for(int i=0; i<a.length; i++){
for(int j = 0; j<a[i].length; j++){
System.out.print(a[i][j]+"\t");
}
System.out.println("\n");
}
}
public static void handle(int x,int y,int l){
int cutl = l/2;
if(cutl>=1){
t++;
if(check(x,y,cutl)){
blo[cutl-1+x][cutl-1+y] = t;
}
if(check(x,y+cutl,cutl)){
blo[cutl-1+x][cutl+y] = t;
}
if(check(x+cutl,y,cutl)){
blo[cutl+x][cutl-1+y] = t;
}
if(check(x+cutl,y+cutl,cutl)){
blo[cutl+x][cutl+y] = t;
}
handle(x,y,cutl);
handle(x,y+cutl,cutl);
handle(x+cutl,y,cutl);
handle(cutl+x,cutl+y,cutl);
}
}
//判断区域内数字是否全是-1
public static boolean check(int x,int y,int l){
boolean q = true;
out:
for(int i=x; i<x+l; i++){
for(int j = y; j<y+l; j++){
if(blo[i][j]!=-1){
q=false;
break out;
}
}
}
return q;
}
}