题目分析
在一个 2k*2k 个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一个特殊方格,且称棋盘为特殊棋盘。
在棋盘覆盖问题中,要用到4中不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格意外的所有方格,且任何2个L型骨牌不得重叠覆盖。
分治法
视频讲解
超简单!棋盘覆盖+代码实现
代码
public class qipan {
int tile = 1;//表示L型骨牌的编号
int[][] board = new int[100][100];//表示棋盘
//处理带有特殊棋子的棋盘.tr、tc表示棋盘的入口即左上角的行列号,dr、dc表示特殊棋子的行列位置,size表示棋盘的大小
public void ChessBoard(int tr, int tc, int dr, int dc, int size) {
if (size == 1) { //如果棋盘大小=1,就说明不能再进行划分
return; //即到达递归边界 返回 退出方法
}
int t = tile++;
int s = size / 2;//每一次化大棋盘为一半的子棋盘
//要处理带有特殊棋子的棋盘,第一步先处理左上棋盘
if (dr < tr + s && dc < tc + s)//左上角子棋盘有特殊棋子
{
ChessBoard(tr, tc, dr, dc, s);
}//处理有特殊棋子的左上角子棋盘
else//处理无特殊棋子的左上角子棋盘
{
//设左上角子棋盘的右下角为特殊棋子,用t型的骨牌覆盖。
board[tr + s - 1][tc + s - 1] = t;
ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);//处理有用骨牌覆盖的格子作为特殊棋子的左上角子棋盘
}
//第二步处理右上角棋盘
if (dr < tr + s && dc >= tc + s)//右上角子棋盘有特殊棋子
{
ChessBoard(tr, tc + s, dr, dc, s);//处理有特殊棋子的右上角子棋盘
} else {
board[tr + s - 1][tc + s] = t;//设右上角子棋盘的左下角为特殊棋子,用t型的骨牌覆盖。
ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);//处理有用骨牌覆盖的格子作为特殊棋子的右上角子棋盘
}
//第三步处理左下角子棋盘
if (dr >= tr + s && dc < tc + s)//左下角子棋盘有特殊棋子
{
ChessBoard(tr + s, tc, dr, dc, s);//处理有特殊棋子的左下角子棋盘
} else {
board[tr + s][tc + s - 1] = t;//设左下角子棋盘的右上角为特殊棋子,用t型的骨牌覆盖。
ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);//处理有用骨牌覆盖的格子作为特殊棋子的左下角子棋盘
}
//第四步处理右下角棋盘
if (dr >= tr + s && dc >= tc + s)//右下角子棋盘有特殊棋子
{
ChessBoard(tr + s, tc + s, dr, dc, s);//处理有特殊棋子的右下角子棋盘
} else {
board[tr + s][tc + s] = t;//设子棋盘右下角的左上角为特殊棋子,用t型的骨牌覆盖。
ChessBoard(tr + s, tc + s, tr + s, tc + s, s);//处理有用 骨牌覆盖的格子作为特殊棋子的右下角子棋盘
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入棋盘的大小(size)");
int size = sc.nextInt(); //棋盘大小
System.out.println("请输入特殊棋子的位置(dr,dc)");
int dr = sc.nextInt();
int dc = sc.nextInt();
//调用方法
qipan c = new qipan();
//(0,0)左上角的方格位置 (dr,dc特殊方格位置) size棋盘大小
c.ChessBoard(0, 0, dr, dc, size);
//输出棋盘
for (int i = 0; i < size; i++) {
for(int j = 0; j < size; j++) {
System.out.print(String.format("%5d", c.board[i][j]));
}
System.out.println();
}
}
}
代码截图