demo
分治法:
package ChessBoard;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int n;//棋盘大小(行)
int i,j;
int dr,dc;//特殊方格的所在行、列
int tr=0,tc=0;//棋盘左上角的行、列
int MAX_SIZE = 100;
int Board[][] = new int[MAX_SIZE][MAX_SIZE];//用来表示棋盘左上角方格
System.out.println("请输入棋盘的行数(必须是2的倍数):");
Scanner in = new Scanner(System.in);
n = in.nextInt();
// n=4;
System.out.println("请输入特殊方格的横纵坐标,如:0行1列: 0 1。");
dr = in.nextInt();
dc = in.nextInt();
// dr=0;
// dc=1;
Board[dr][dc] = -1;
ChessBoard.ChessBoard(Board,tr,tc,dr,dc,n);
String str_out = "";
for(i=0;i<n;i++){
for(j=0;j<n;j++){
str_out += Board[i][j];
str_out += " ";
}
System.out.println(str_out);
str_out = "";
}
System.out.println("其中 -1 表示特殊方格");
}
}
package ChessBoard;
public class ChessBoard {
private static int MAX_SIZE = 4;
private static int tile = 0;//用来表示L型骨牌的编号
/**
* 棋盘覆盖函数
* @param tr 棋盘左上角的行
* @param tc 棋盘左上角的列
* @param dr 特殊方格横坐标
* @param dc 特殊方格纵坐标
* @param size 棋盘行数和列数
*/
public static void ChessBoard(int Board[][],int tr,int tc,int dr,int dc,int size){
if(size==1)
return;
int t = tile++,//L型骨牌号
s=size/2;//分割棋盘
//覆盖左上角子棋盘
if(dr<tr+s&&dc<tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr,tc,dr,dc,s);
}
else{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖右下角
Board[tr+s-1][tc+s-1]=t;
ChessBoard(Board,tr,tc,tr+s-1,tc+s-1,s);//覆盖其余方格
}
//覆盖右上角子棋盘
if(dr<tr+s&&dc>=tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr,tc+s,dr,dc,s);
}
else{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖左下角
Board[tr+s-1][tc+s]=t;
ChessBoard(Board,tr,tc+s,tr+s-1,tc+s,s);//覆盖其余方格
}
//覆盖左下角子棋盘
if(dr>=tr+s&&dc<tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr+s,tc,dr,dc,s);
}
else{ //用t号L型骨牌覆盖右上角
Board[tr+s][tc+s-1]=t;
ChessBoard(Board,tr+s,tc,tr+s,tc+s-1,s);//覆盖其余方格
}
//覆盖右下角子棋盘
if(dr>=tr+s&&dc>=tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr+s,tc+s,dr,dc,s);
}
else{ //用t号L型骨牌覆盖左上角
Board[tr+s][tc+s]=t;
ChessBoard(Board,tr+s,tc+s,tr+s,tc+s,s);//覆盖其余方格
}
}
/**
* 棋盘覆盖函数:优化
* @param tr 棋盘左上角的行
* @param tc 棋盘左上角的列
* @param dr 特殊方格横坐标
* @param dc 特殊方格纵坐标
* @param size 棋盘行数和列数
*/
public static void ChessBoard_advance(int Board[][],int tr,int tc,int dr,int dc,int size){
if(size==1)
return;
int t = tile++,//L型骨牌号
s=size/2;//分割棋盘
//覆盖左上角子棋盘
if(dr<tr+s&&dc<tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr,tc,dr,dc,s);
}
else{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖右下角
Board[tr+s-1][tc+s-1]=t;
ChessBoard(Board,tr,tc,tr+s-1,tc+s-1,s);//覆盖其余方格
}
//覆盖右上角子棋盘
if(dr<tr+s&&dc>=tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr,tc+s,dr,dc,s);
}
else{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖左下角
Board[tr+s-1][tc+s]=t;
ChessBoard(Board,tr,tc+s,tr+s-1,tc+s,s);//覆盖其余方格
}
//覆盖左下角子棋盘
if(dr>=tr+s&&dc<tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr+s,tc,dr,dc,s);
}
else{ //用t号L型骨牌覆盖右上角
Board[tr+s][tc+s-1]=t;
ChessBoard(Board,tr+s,tc,tr+s,tc+s-1,s);//覆盖其余方格
}
//覆盖右下角子棋盘
if(dr>=tr+s&&dc>=tc+s){ //特殊方格在此棋盘中
ChessBoard(Board,tr+s,tc+s,dr,dc,s);
}
else{ //用t号L型骨牌覆盖左上角
Board[tr+s][tc+s]=t;
ChessBoard(Board,tr+s,tc+s,tr+s,tc+s,s);//覆盖其余方格
}
}
}
复杂度分析
覆盖一个2^k * 2^k棋盘所需时间复杂度:
T(k) = 4T(k-1) + O(1) = O(4^k)