若棋盘规格是1*1,则不用填充;
若棋盘规格大于1*1,则将棋盘分割成四个子棋盘。判断特殊点在哪一个子棋盘中,进入该棋盘继续覆盖,而对其他子棋盘,设置边界点为新特殊点(填充这3个边界点即是填充了一个L型骨牌),并对各个子棋盘继续覆盖。
- #include<iostream>
- using namespace std;
- #define N 10 // 最大棋盘size
- int Board[N][N]; // 棋盘矩阵
- int tile = 1; // 当前骨牌编号
- /**************************************************************
- * 棋盘覆盖分治算法
- *
- * 输入:棋盘起始点坐标tr,tc,特殊点坐标dr,dc,棋盘规格小size
- * 输出:覆盖好的棋盘矩阵Board[][]
- **************************************************************/
- void ChessBoard(int tr, int tc, int dr, int dc, int size){
- if(size==1)return; // 若棋盘大小为1则返回
- int t = tile++, // 当前要填充的骨牌号
- s = size/2; // 分割的棋盘规格
- // 若特殊点在左上角棋盘
- if(dr<tr+s&&dc<tc+s){
- // 特殊方格在此棋盘中
- ChessBoard(tr,tc,dr,dc,s);
- }else{
- // 将该棋盘的右下角点填充骨牌,使其成为新特殊点
- 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;
- 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;
- 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;
- ChessBoard(tr+s, tc+s, tr+s, tc+s, s);
- }
- }
- int main(){
- int n,i,j,x,y;
- // 输入棋盘规格和特殊点坐标x,y
- cin>>n>>x>>y;
- // 初始化棋盘矩阵
- memset(Board,0,sizeof(Board));
- // 覆盖棋盘
- ChessBoard(0,0,x,y,n);
- // 输出覆盖后的棋盘矩阵
- for(i=0;i<n;i++){
- for(j=0;j<n;j++){
- printf("%5d",Board[i][j]);
- }
- cout<<endl;
- }
- return 0;
- }