package 分治回溯;
/*
利用分治法,将方形棋盘分为四个部分
如果该特殊点在其中的某一部分,我们就接着去递归处理即可
如果不存在特殊点的部分,我们假设一个特殊点,同样的递归下去即可
直到全覆盖位置
左上角的棋盘 若不存在特殊点 该棋盘的右下角为特殊点
右上角的棋盘 若不存在特殊点 该棋盘的左下角为特殊点
左下角的棋盘 若不存在特殊点 该棋盘的右上角为特殊点
右下角的棋盘 若不存在特殊点 该棋盘的左上角为特殊点
*/
import java.util.Scanner;
public class ChessboardCoverage {
//定义棋盘的大小2^k*2^k
private static int BOARD_SIZE=8;
//定义一个二维数组模拟棋盘
private static int [][] board=new int[BOARD_SIZE][BOARD_SIZE];
//定义一个骨牌的编号
private static int title=0;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("棋盘的大小为:"+BOARD_SIZE);
System.out.print("请输入特殊方格的行号:");
int dr=scanner.nextInt();
System.out.print("请输入特殊方格的列号:");
int dc=scanner.nextInt();
//开始递归解决问题
chessBoard(0,0,dr-1,dc-1,BOARD_SIZE);
print();
}
/*
tr tc 指的是某一个方形的左上角坐标(突然,tc)
dr dc 指的是特殊方格的坐标(等人,dc)
size 指的是当前方格的尺寸
*/
private static void chessBoard(int tr, int tc, int dr, int dc, int size) {
if (size==1){
return;
}
//当前层级下的骨牌的编号
int num=++title;
//子方格的尺寸
int s=size/2;
//1.左上角子方格
if (dr<tr+s&&dc<tc+s){
//特殊方格在在右上角
chessBoard(tr,tc,dr,dc,s);
}else {
//特殊方格不在左上角
board[tr+s-1][tc+s-1]=num;
chessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
//2.右上角自方格
if (dr<tr+s&&dc>=tc+s){
chessBoard(tr,tc+s,dr,dc,s);
}else {
board[tr+s-1][tc+s]=num;
chessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
//3.左下角子方格
if (dr>=tr+s&&dc<tc+s){
chessBoard(tr+s,tc,dr,dc,s);
}else {
board[tr+s][tc+s-1]=num;
chessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
//4.右下角子方格
if (dr>=tr+s&&dc>=tc+s){
chessBoard(tr+s,tc+s,dr,dc,s);
}else {
board[tr+s][tc+s]=num;
chessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
private static void print(){
for (int i=0;i<BOARD_SIZE;i++){
for (int j=0;j<BOARD_SIZE;j++){
System.out.print(board[i][j]+"\t");
}
System.out.println();
}
}
}
执行结果
棋盘的大小为:8
请输入特殊方格的行号:2
请输入特殊方格的列号:3
3 3 4 4 8 8 9 9
3 2 0 4 8 7 7 9
5 2 2 6 10 10 7 11
5 5 6 6 1 10 11 11
13 13 14 1 1 18 19 19
13 12 14 14 18 18 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21