棋盘覆盖问题算法分析与实现(递归)
2017-05-12 17:51
681 查看
*昨天上传的代码,经过再次测试发现有问题,其中对边界、终止条件的判断都有错误。。。→_→,今天重新改正,对之前看过代码的童鞋表示sorry。。。(2017.5.13 16:24)*
问题描述:
在一个2^k×2^k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中可能出现的位置有4^k种,因而有4^k种不同的棋盘。棋盘覆盖问题(chess cover problem)要求使用4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
关于棋盘划分的更多概念请戳传送门:棋盘覆盖问题
实现如下:
测试用例:
问题描述:
在一个2^k×2^k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中可能出现的位置有4^k种,因而有4^k种不同的棋盘。棋盘覆盖问题(chess cover problem)要求使用4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
关于棋盘划分的更多概念请戳传送门:棋盘覆盖问题
实现如下:
class Solution { public: int num = 0;//累计计算 int **board = NULL;//动态二维数组指针 void printBoard(int **board, int row, int col)//输出函数 { for (int i = 0; i < row; ++i) { for (int j = 0; j < col; ++j) cout << setw(3) <<board[i][j]; cout << endl; } cout << endl; } void createBoard(int chessboardSize, int dr, int dc)//动态申请内存函数 { board = (int **)malloc(chessboardSize * sizeof(int*)); assert(board != NULL); for (int i = 0; i < chessboardSize; ++i) { board[i] = (int*)malloc(chessboardSize * sizeof(int)); assert(board[i] != NULL); memset(board[i], 0, sizeof(int)*chessboardSize); } board[dr][dc] = -1;//将特殊点设置为-1 } void freeBoard(int row)//释放动态内存空间,防止内存泄漏 { for (int i = 0; i < row; ++i) free(board[i]); free(board); } //chessboardSize表示此时范围的n*n,n的值 //dr表示特殊点的行下标 //dc表示特殊点的列下标 //tr表示此时范围的左上角在数组中的行下标 //tc表示此时范围的左上角在数组中的列下标 void Coverage(int chessboardSize, int dr, int dc, int tr, int tc) { if (chessboardSize == 1) return;//当范围为1时,表示只有一个元素,return int tmp = ++num;//每进入一个范围内,num累加 int s = chessboardSize / 2;//获取此时范围内的下一个小范围的n大小 //判断特殊点是否在范围内的第一象限 if (dr < tr + s && dr >= 0 && dc < tc + s && dc >= 0) Coverage(s, dr, dc, tr, tc); else//否则,将此第一象限的右下角设置为相对特殊点 { board[tr + s - 1][tc + s - 1] = tmp; Coverage(s, tr + s - 1, tc + s - 1, tr, tc); } //判断特殊点是否在范围内的第四象限 if (dr >= 0 && dr < tr + s && dc >= tc + s && dc < tc + 2 * s) Coverage(s, dr, dc, tr, tc + s); else//否则,将此第四象限的右下角设置为相对特殊点 { board[tr + s - 1][tc + s] = tmp; Coverage(s, tr + s - 1, tc + s, tr, tc + s); } //判断特殊点是否在范围内的第二象限 if (dr >= tr + s && dr < tr + 2 * s && dc >= 0 && dc < tc + s) Coverage(s, dr, dc, tr + s, tc); else//否则,将此第二象限的右下角设置为相对特殊点 { board[tr + s][tc + s - 1] = tmp; Coverage(s, tr + s, tc + s - 1, tr + s, tc); } //判断特殊点是否在范围内的第三象限 if (dr >= tr + s && dr < tr + 2 * s && dc >= tc + s && dc < tc + 2 * s) Coverage(s, dr, dc, tr + s, tc + s); else//否则,将此第三象限的右下角设置为相对特殊点 { board[tr + s][tc + s] = tmp; Coverage(s, tr + s, tc + s, tr + s, tc + s); } //printBoard(board, 8, 8); } void ChessboardCoverage(int chessboardSize, int dr, int dc) { if (chessboardSize < 1 || dr < 0 || dc < 0 || dr >= chessboardSize || dc >= chessboardSize) return;//防御性动作 createBoard(chessboardSize, dr, dc);//动态生成二维数组 Coverage(chessboardSize, dr, dc, 0, 0);//开始覆盖 printBoard(board, chessboardSize, chessboardSize);//输出 freeBoard(chessboardSize);//释放动态空间 } };
测试用例:
相关文章推荐
- 棋盘覆盖问题的算法实现
- 算法[递归]-棋盘覆盖问题
- 高效算法设计_递归与分治(棋盘覆盖问题,循环日程表,巨人与鬼)
- 棋盘覆盖问题(算法分析)(Java版)
- 棋盘覆盖问题的算法实现
- 算法java实现--分治法--棋盘覆盖问题
- 用递归法:设计算法求解汉诺塔问题,并编程实现。 (1) Hanoi(汉诺)塔问题分析 这是一个古典的数学问题,是一个用递归方法解题的典型例子。问题是这样的:古代有一个梵塔,塔内有3个座 A,B,C
- 计算机算法设计与分析之棋盘覆盖问题
- 求子集问题算法分析与实现(递归、非递归)
- 算法分析与设计之棋盘覆盖问题
- 棋盘覆盖问题的算法实现
- 计算机算法设计与分析作业01:分治法求解大数乘法+L型骨牌的棋盘覆盖问题
- 全排列问题算法分析与实现(递归、非递归)
- 计算机算法设计与分析之棋盘覆盖问题
- 分治算法之 棋盘覆盖问题(完整代码实现)
- 整数划分问题算法分析与实现(递归)
- 常用算法的递归实现问题分析(针对《数据结构与程序设计》by Robert.L.Kruse)
- 棋盘覆盖 算法分析、设计与实现(Java)
- 棋盘覆盖问题的算法实现
- 算法分析与设计之棋盘覆盖问题