#include<cstdio>
//using namespace std;
int tile=1;//编号
int board[100][100];//棋盘
/*tr--当前棋盘左上角的行号
* tc--当前棋盘左上角的列号
* dr--当前特殊方格所在的行号
* dc--当前特殊方格所在的列号
* size:当前棋盘的:2^k */
//就是递归一个方块中有一个特殊方块的状态,没有特殊方块,要创造方块,并且这个创造的就是本轮确定的编号
void chessboard(int tr,int tc,int dr,int dc,int size){
//主要是通过确定特殊块不在的三个方块的中间的每次递增一个块。
//注意,每次递归的时候,特殊块的编号已经确定了,是先确定了这个块的变化,然后再视为特殊块,并且递归的
if(size==1)//棋盘方格大小为,说明递归到最里层
return;
int t=tile++;//每次递增1.
int 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;//注意我一开始把行的标号写少了一个
}
//检查是否在左下角的棋盘中
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 size,index_x,index_y;
scanf("%d%d%d",&size,&index_x,&index_y);
chessboard(0,0,index_x,index_y,size);
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
printf("%-3d",board[i][j]);
}
printf("\n");
}
return 0;
}
分治 棋盘覆盖 超级好理解的一种写法!
最新推荐文章于 2024-11-13 16:53:13 发布