算法设计与分析:第三章 分治 3.6棋盘覆盖
2015-08-05 09:50
471 查看
/* 棋盘覆盖: 在一个2k×2k 个方格组成的棋盘中,恰有一个方格 与其它方格不同,称该方格为一特殊方格,且称该棋 盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种 不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格 以外的所有方格,且任何2个L型骨牌不得重叠覆盖。 当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘 (a)所示。特殊方格必位于4个较小子棋盘之一中,其 余3个子棋盘中无特殊方格。为了将这3个无特殊方格 的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这 3个较小棋盘的会合处,如 (b)所示,从而将原问题转 化为4个较小规模的棋盘覆盖问题。递归地使用这种分 割,直至棋盘简化为棋盘1×1。 关键是: 如果不在棋盘左上,就设置右下角为指定颜色 右上, 左下 左下 右上 右下 左上 输入: 输入: 行 列 k(2^k为棋盘长度) 0 1 2(左上角测试) 1 3 2(右上角测试) 3 0 2(左下角测试) 2 2 2 (右下角测试) 输出: 2 0 3 3 2 2 1 3 4 1 1 5 4 4 5 5 2 2 3 3 2 1 3 0 4 1 1 5 4 4 5 5 2 2 3 3 2 1 1 3 4 4 1 5 0 4 5 5 2 2 3 3 2 1 1 3 4 1 0 5 4 4 5 5 */ /* 关键: 1将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘 (a)所示。特殊方格必位于4个较小子棋盘之一中,其 余3个子棋盘中无特殊方格。为了将这3个无特殊方格 的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这 3个较小棋盘的会合处, 2如果不在棋盘左上,就设置右下角为指定颜色 右上, 左下 左下 右上 右下 左上 3 //分治第二步:递归处理 //判断特殊标记是否在左上角 if(iColorRow < iBegRow + iHalfSize && iColorCol < iBegCol + iHalfSize) { //如果特殊标记在左上角,那么左上角区域递归处理 chessCover(iBegRow,iBegCol,iColorRow,iColorCol,iHalfSize,pChessBoard); } else { //如果不在左上角,那么设置左上角区域中的最右下角位置为特殊标记。区域重新设置,起始行列:要随区域的不同而改变,左上不需改变,右上的列需要改为原列+棋盘半长 pChessBoard[iBegRow + iHalfSize - 1][iBegCol + iHalfSize - 1] = iMarkNum; //更新特殊标记为刚才设置的特殊标记 chessCover(iBegRow,iBegCol,iBegRow + iHalfSize - 1,iBegCol + iHalfSize - 1,iHalfSize,pChessBoard); } 4 printf("%-4d ",pChessBoard[i][j]);//左对齐为"-" */ #include<stdio.h> const int MAXSIZE = 100; int g_iDominoNum; int my_pow(int iBase,int iExp) { if(iExp == 1) { return iBase; } int iRet = my_pow(iBase,iExp/2); iRet *= iRet; if(iExp % 2 == 1) { iRet *= iBase; } return iRet; } void chessCover(int iBegRow,int iBegCol,int iColorRow,int iColorCol,int iSize,int pChessBoard[][MAXSIZE]) { if(iSize == 1) { return; } int iMarkNum = g_iDominoNum++; //分治第一步:划分 int iHalfSize = iSize/2; //分治第二步:递归处理 //判断特殊标记是否在左上角 if(iColorRow < iBegRow + iHalfSize && iColorCol < iBegCol + iHalfSize) { //如果特殊标记在左上角,那么左上角区域递归处理 chessCover(iBegRow,iBegCol,iColorRow,iColorCol,iHalfSize,pChessBoard); } else { //如果不在左上角,那么设置左上角区域中的最右下角位置为特殊标记。区域重新设置,起始行列:要随区域的不同而改变,左上不需改变,右上的列需要改为原列+棋盘半长 pChessBoard[iBegRow + iHalfSize - 1][iBegCol + iHalfSize - 1] = iMarkNum; //更新特殊标记为刚才设置的特殊标记 chessCover(iBegRow,iBegCol,iBegRow + iHalfSize - 1,iBegCol + iHalfSize - 1,iHalfSize,pChessBoard); } //右上区域进行判断 if(iColorRow < iBegRow + iHalfSize && iColorCol >= iBegCol + iHalfSize) { chessCover(iBegRow,iBegCol + iHalfSize,iColorRow,iColorCol,iHalfSize,pChessBoard); } else { //不在右上区域,则令最左下区域为特殊标记。使其行成为不超出界的最大,列为超出界的最小 pChessBoard[iBegRow + iHalfSize - 1][iBegCol + iHalfSize] = iMarkNum; //对右上区域递归处理 chessCover(iBegRow,iBegCol + iHalfSize,iBegRow + iHalfSize - 1,iBegCol + iHalfSize,iHalfSize,pChessBoard); } //左下区域 if(iColorRow >= iBegRow + iHalfSize && iColorCol < iBegCol + iHalfSize) { chessCover(iBegRow + iHalfSize,iBegCol,iColorRow,iColorCol,iHalfSize,pChessBoard); } else { //左下另右上特殊标记 pChessBoard[iBegRow + iHalfSize][iBegCol + iHalfSize - 1] = iMarkNum; chessCover(iBegRow + iHalfSize,iBegCol,iBegRow + iHalfSize,iBegCol + iHalfSize - 1,iHalfSize,pChessBoard); } //右下区域 if(iColorRow >= iBegRow + iHalfSize && iColorCol >= iBegCol + iHalfSize) { chessCover(iBegRow + iHalfSize,iBegCol + iHalfSize,iColorRow,iColorCol,iHalfSize,pChessBoard); } else { //左下另右上特殊标记 pChessBoard[iBegRow + iHalfSize][iBegCol + iHalfSize] = iMarkNum; chessCover(iBegRow + iHalfSize,iBegCol + iHalfSize,iBegRow + iHalfSize,iBegCol + iHalfSize ,iHalfSize,pChessBoard); } } void printGraph(int pChessBoard[][MAXSIZE],int iBoardSize) { for(int i = 0 ; i < iBoardSize ; i++) { for(int j = 0 ; j < iBoardSize ; j++) { printf("%-4d ",pChessBoard[i][j]);//左对齐为"-" } printf("\n"); } } void process() { int iColorRow,iColorCol,iSize; int iArr_ChessBoard[MAXSIZE][MAXSIZE]; while(EOF != scanf("%d %d %d",&iColorRow,&iColorCol,&iSize)) { if(iColorRow < 0 || iColorRow < 0 || iSize <= 0) { break; } int iBoardSize = my_pow(2,iSize); g_iDominoNum = 1;//用于绘制不同的骨牌 iArr_ChessBoard[iColorRow][iColorCol] = 0; chessCover(0,0,iColorRow,iColorCol,iBoardSize,iArr_ChessBoard); printGraph(iArr_ChessBoard,iBoardSize); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 算法设计与分析:第三章 分治 3.5Strassen矩阵乘法
- Silverlight 2 (beta1)数据操作(2)——使用ASP.NET Web Service进行数据CRUD操作(下)
- [转]在linux下如何判断是否已经安装某个软件?软件安装在哪个目录
- C语言冒泡排序实现
- http get post传参
- HDU--5344--2015 Multi-University Training Contest 5--MZL's xor
- 一个可以下载所有操作系统的网站
- 算法设计与分析:第三章 分治 3.3二进制大整数的乘法
- 算法设计与分析:第三章 分治 3.4多项式乘积的分治方法
- 算法设计与分析:第三章 分治 3.2正整数划分
- 代码整洁之道--注释,格式
- C语言冒泡排序
- c++加密解密算法用java方法替代
- HTTP POST请求报文格式分析与Java实现文件上传
- htons函数详解
- 6种常见的数据加载模式设计
- double my_atof(char *str)
- 机器学习05(SVM理论推导)
- Codeforces 443B Kuriyama Mirai's Stones
- poj 2065 高斯消元取模解方程组