分治法:棋盘覆盖问题
YOYO
posted @ 2009年4月29日 08:05
in 【算法】与【数据结构】
with tags
分治
, 3376 阅读
若棋盘规格是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;
-
}