题目描述
Tromino 是指一个由棋盘上的三个方块组成的 L 型骨牌。如何用 Tromino 覆盖一个缺
少了一个方块(可以在棋盘上任何位置)的棋盘(下图展示了情况)。除了这个缺失的方
块,Tromino 应该覆盖棋盘上的所有方块,Tromino 可以任意转向但不能有重叠。
实现思想
使用变量标记区域坐标信息,随机生成L区域颜色。使用L区域的3个格子和随机生成的一个格子把每一个象限里都实现涂鸦一个格子。然后递归调用函数把每一个区域涂鸦,直到剩下的区域尺寸为2x2时结束调用。
数据结构:变量储存坐标信息
实现步骤:L区域的3个格子和随机生成的一个格子把每一个象限里都实现涂鸦一个格子。然后递归调用函数把每一个区域涂鸦,知道剩下的区域尺寸为2x2时结束调用。
实现技巧:递归的去实现涂鸦每一个象限的方格,我认为时很方便的处理方法。这样可以避免处理循环以及各种问题。
时间复杂度为:O(n^2)
空间复杂度:O(n^2)
结果
代码
package CourseDesign;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.Random;
public class A1 extends Application {
Group group = new Group();
Scene scene = new Scene(group, 800, 800);
Rectangle rectangle = null;
@Override
public void start(Stage primaryStage) throws Exception {
// ***************
int pow = 16;//界面
int size = 50;//小格子的大小
//****************
Random random = new Random();
// 画线
for (int i = 0; i < pow + 1; i++) {
// 横线
Line line = new Line(0, i * size, 50 * pow, i * size);
line.setStroke(Color.RED);
group.getChildren().add(line);
// 竖线
line = new Line(i * size, 0, i * size, 50 * pow);
line.setStroke(Color.RED);
group.getChildren().add(line);
}
// 最开始的黑点
int x = random.nextInt(pow) * size;
int y = random.nextInt(pow) * size;
rectangle = new Rectangle(x, y, size, size);
group.getChildren().add(rectangle);
// 建立一个线程开始涂棋盘
Thread thread = new Thread(() -> {
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
Runnable runnable = () -> tromino(primaryStage, x, y, pow, 0, 0, size);
// 使用Platform启动线程
Platform.runLater(runnable);
});
// 设置线程属性
thread.setDaemon(true);
thread.start();
primaryStage.setScene(scene);
primaryStage.setTitle("primaryStage");
primaryStage.show();
}
// 涂颜色函数
private void tromino(Stage primaryStage, int x, int y, int pow, int x0, int y0, int size) {
// 初始化随机颜色
Random random = new Random();
int c1 = random.nextInt(256);
int c2 = random.nextInt(256);
int c3 = random.nextInt(256);
// 的到中点
int xCenter = x0 + pow / 2 * size;
int yCenter = y0 + pow / 2 * size;
// 其他三个象限的左上角坐标
int x1, x2, x3, y1, y2, y3;
// 判断象限再进行递归每一个象限涂色
if (pow > 2) {
if (xCenter > x) {
x1 = xCenter;
y1 = yCenter;
rectangle = new Rectangle(xCenter, yCenter, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
x2 = xCenter;
y2 = yCenter - size;
rectangle = new Rectangle(xCenter, yCenter - size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
if (yCenter > y) {
x3 = xCenter - size;
y3 = yCenter;
rectangle = new Rectangle(xCenter - size, yCenter, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
} else {
x3 = xCenter - size;
y3 = yCenter - size;
rectangle = new Rectangle(xCenter - size, yCenter - size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
} else {
x1 = xCenter - size;
y1 = yCenter;
rectangle = new Rectangle(xCenter - size, yCenter, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
x2 = xCenter - size;
y2 = yCenter - size;
rectangle = new Rectangle(xCenter - size, yCenter - size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
if (yCenter - y > 0) {
x3 = xCenter;
y3 = yCenter;
rectangle = new Rectangle(xCenter, yCenter, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
} else {
x3 = xCenter;
y3 = yCenter - size;
rectangle = new Rectangle(xCenter, yCenter - size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
}
// 建立线程开始继续画棋盘
Thread thread = new Thread(() -> {
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
Runnable runnable = () -> {
int[] xy = at(xCenter, yCenter, x1, y1, pow / 2, size);
tromino(primaryStage, x1, y1, pow / 2, xy[0], xy[1], size);
xy = at(xCenter, yCenter, x2, y2, pow / 2, size);
tromino(primaryStage, x2, y2, pow / 2, xy[0], xy[1], size);
xy = at(xCenter, yCenter, x3, y3, pow / 2, size);
tromino(primaryStage, x3, y3, pow / 2, xy[0], xy[1], size);
xy = at(xCenter, yCenter, x, y, pow / 2, size);
tromino(primaryStage, x, y, pow / 2, xy[0], xy[1], size);
};
Platform.runLater(runnable);
});
thread.setDaemon(true);
thread.start();
} else {
if (x0 != x || y0 != y) {
rectangle = new Rectangle(x0, y0, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
if (x0 + size != x || y0 != y) {
rectangle = new Rectangle(x0 + size, y0, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
if (x0 != x || y0 + size != y) {
rectangle = new Rectangle(x0, y0 + size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
if (x0 + size != x || y0 + size != y) {
rectangle = new Rectangle(x0 + size, y0 + size, size, size);
rectangle.setFill(Color.rgb(c1, c2, c3));
group.getChildren().add(rectangle);
}
}
}
/**
* 返回点所在象限的左上角坐标
*
* @param xCenter 中心坐标
* @param yCenter 中心坐标
* @param x 点坐标
* @param y 点坐标
* @param len 长度,pow的一半
* @return n0 x,n1 y
*/
private int[] at(int xCenter, int yCenter, int x, int y, int len, int size) {
int[] n = new int[2];
n[0] = x >= xCenter ? xCenter : xCenter - len * size;
n[1] = y >= yCenter ? yCenter : yCenter - len * size;
return n;
}
public static void main(String[] args) {
launch(args);
}
}