分治 棋盘覆盖 超级好理解的一种写法!

#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;
}

你可能感兴趣的:(分治,棋盘覆盖)