读书人

分治算法之 棋盘覆盖有关问题(完整代

发布时间: 2013-03-27 11:22:42 作者: rapoo

分治算法之 棋盘覆盖问题(完整代码实现)

我在这里是用了一个简化的方式,只是代码简化,还是分治递归思想。一分为4,直至2*2时可直接解决。

四种骨牌的摆放刚好对应:dir[4][2] = { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 1, 0 } }; 这四个方向。

而这4个方向,又可用来判断残缺位置的 4个方向(左上,右上,右下,左下)。

因此可以用循环,而不是依次判断四个方向,简化代码。

也可以用一个全局变量title 表示第几个骨牌,然后输出的时候可以用一个title代替ABCD.

copy:

【解题思路】:将2^k x 2^k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘,将他们中的也假一个方格设为特殊方格。如果是:

左上的子棋盘(若不存在特殊方格)----则将该子棋盘右下角的那个方格假设为特殊方格
右上的子棋盘(若不存在特殊方格)----则将该子棋盘左下角的那个方格假设为特殊方格
左下的子棋盘(若不存在特殊方格)----则将该子棋盘右上角的那个方格假设为特殊方格
右下的子棋盘(若不存在特殊方格)----则将该子棋盘左上角的那个方格假设为特殊方格

当然上面四种,只可能且必定只有三个成立,那三个假设的特殊方格刚好构成一个L型骨架,我们可以给它们作上相同的标记。这样四个子棋盘就分别都和原来的大棋盘类似,我们就可以用递归算法解决。


欢迎使用棋盘覆盖程序:分别A,B,C,D代表4种不同方向的骨牌:  A    B     CC   DDAA    BB    C     D输入3个数,分别为棋盘大小N(小于1000),残缺位置X,Y(1到N之间):4 2 3CCDDCB DBBBABBAA



这是书上的代码(不全):

void ChessBoard(int tr, int tc, int dr,int dc, int size)

{ if (size==1) return;

int t=tile++,// L型骨牌数

s=size/2; // 分割棋盘

//覆盖左上角子棋盘

if (dr< tr +s && dc < tc+S)

//特殊方格在此棋盘中

ChessBoard(tr, tc, dr,dc,S);

else{//此棋盘中无特殊方格

//用t号L型骨牌覆盖右下角

Board[tr+s-1][tc+s-1]=t;

//覆盖其余方格

Chessboard(tr,tc,tr+s-1,tc+s-l,s);}

//覆盖右上角子棋盘

if (dr <= tr +s && dc >= tc+S)

//特殊方格在此棋盘中

ChessBoard(tr,tc+s ,dr,dc,S);

else{//此棋盘中无特殊方格

//用t号骨牌覆盖左下角

Board[tr+s-1][tc+s]=t;

//覆盖其余方格

Chessboard(tr,tc+s,tr+s-1,tc+s,s);}

………………...

void outputBoard( int size)

{ for inti=0;i<size;i++){

for intj=0 ;j<size ;j++);

cout<<setw(5)<<board [i][j];

cout<<endl;}}



读书人网 >编程

热点推荐