首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2013-03-27 
分治算法之 棋盘覆盖问题(完整代码实现)我在这里是用了一个简化的方式,只是代码简化,还是分治递归思想。一

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

我在这里是用了一个简化的方式,只是代码简化,还是分治递归思想。一分为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;}}



热点排行