分治法,棋盘覆盖

来源:互联网 发布:js 设置div display 编辑:程序博客网 时间:2024/05/16 01:55
//分治法--棋盘覆盖问题  //问题描述:在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,//且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用4不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,//且任何2个L型骨牌不得重叠覆盖。//思想:将2^k x 2^k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘,//将他们中的也假一个方格设为特殊方格。如果是://左上的子棋盘(若不存在特殊方格)----则将该子棋盘右下角的那个方格假设为特殊方格//右上的子棋盘(若不存在特殊方格)----则将该子棋盘左下角的那个方格假设为特殊方格//左下的子棋盘(若不存在特殊方格)----则将该子棋盘右上角的那个方格假设为特殊方格//右下的子棋盘(若不存在特殊方格)----则将该子棋盘左上角的那个方格假设为特殊方格//当然上面四种,只可能且必定只有三个成立,那三个假设的特殊方格刚好构成一个L型骨架,我们可以给它们作上相同的标记。//这样四个子棋盘就分别都和原来的大棋盘类似,我们就可以用递归算法解决。//算法说明:用一个二维整形数组board表示棋盘,board【0】【0】是棋盘左上角方格,//tile是算法中的一个全局整型变量,用来表示骨牌编号,初始值为0//参数:tr是棋盘左上角的方格行号//      tc是棋盘左上角的方格列号//      dr是特殊方格所在行号//      dc是特殊放个所在列号//      size是2^k,棋盘是 2^k*2^k的//      此程序可以实现检测是否可以覆盖//      因为骨牌个数是4^k/3,只需检测是否是整数 //本题即使要求,将图形分割,变为4个格子的大小,然后4个格子中有一个被覆盖,另外3个格子被新的一个覆盖 #include<iostream>#include<iomanip>using namespace std;int board[8][8]={0};int tile=1;                                            //tile骨牌编号 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);                //继续调用 }                                               //分别对左上,左下,右上,右下位置寻找或覆盖,直至k==1停止 //右上角 if(dc>=tc+s&&dr<tr+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(dc>=tc+s&&dr>=tr+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(){chessboard(0,0,0,7,8);                      //特殊格子位置,在[0,7],图形规模为2的3次方 for(int i=0 ; i<8 ; i++)      for(int j=0 ; j<8 ; j++)        {           cout  << setw(3) << board[i][j];           if(j==7)             cout << endl ;        }         return 0;      }//输出即为格子覆盖状况,同一标号为同一图形 //fout<<setw(x)<<n(x>0)相对于右对齐x位//cout<<setw(x)<<n(x<0)相对于左对齐-x位 
2 0
原创粉丝点击