棋盘覆盖问题
问题说明
在一个2^k * 2^k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格。
棋盘覆盖问题就是要用图示的4种不同形态的L型骨牌覆盖给定棋盘上除特殊方格之外的所有方格,且任何2个L型骨牌不得重叠覆盖。
功能说明
本程序用分治法的思想解决了棋盘覆盖问题,显示输出
代码简述
用户输入数据,程序输入检测,动态分配空间,调用棋盘覆盖函数,把计算结果存储到board(二维数组指针),显示输出。
其中棋盘覆盖函数用分治的思想把棋盘分成四份,递归求解。
源码示例:
#include《iostream》#include《math.h》#include《cctype》usingnamespacestd;intnum_Now =0;//记录L型骨牌编号int**board =NULL;//棋盘指针//函数声明
voidChessBoard(intnum_BoardTopLeftRow,intnum_BoardTopLeftColumn,intnum_SpecialRow,intnum_SpecialColumn,intboardSize);intmain() {intnum_BoardTopLeftRow =0,//棋盘左上角的行号
num_BoardTopLeftColumn =0,//棋盘左上角的列号num_SpecialRow =0,//特殊方格所在的行号num_SpecialColumn =0,//特殊方格所在的列号boardSize =0,//棋盘大小k =0;//构成的(2^k)*(2^k)个方格的棋盘
//用户界面cout 《《“---------------- 棋盘覆盖问题 ----------------”《《 endl;cout 《《“请输入k(k》=0),构成(2^k)*(2^k)个方格的棋盘”《《 endl;//输入k值cin 》》 k;//判断输入数据合法性,包括检查输入是否为数字,k值是否大于0if(cin.fail() || k 《0){cout 《《“输入k错误!”《《 endl;system(“pause”);
return0;}//计算棋盘大小
boardSize =pow(2, k);cout 《《“请输入特殊方格所在的行号和列号(从0开始,用空格隔开)”《《 endl;//输入特殊方格所在的行号和列号cin 》》 num_SpecialRow 》》 num_SpecialColumn;//判断输入数据合法性,包括检查输入是否为数字,特殊方格行号列号是否大于0,特殊方格行号列号是否不大于棋盘大小
if(cin.fail() || num_SpecialRow 《0|| num_SpecialColumn 《0|| num_SpecialRow 》= boardSize || num_SpecialColumn 》= boardSize){cout 《《“输入行号或列号错误!”《《 endl;system(“pause”);return0;}//分配棋盘空间
board =newint*[boardSize];for(autoi =0; i 《 boardSize; i++){board[i] =newint[boardSize];}//为特殊方格赋初值
0board[num_SpecialRow][num_SpecialColumn] =0;//执行棋盘覆盖函数
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, boardSize);//显示输出
cout 《《“------------------------------------------------”《《 endl;for(autoi =0; i 《 boardSize; i++){for(autoj =0; j 《 boardSize; j++){cout 《《 board[i][j] 《《“ ”;}cout 《《 endl;}cout 《《“------------------------------------------------”《《 endl;//暂停查看结果
system(“pause”);//释放内存for(inti =0; i 《= boardSize; i++)delete[]board[i];delete[]board;//指针置空board =NULL;return0;}//棋盘覆盖函数
voidChessBoard(intnum_BoardTopLeftRow,intnum_BoardTopLeftColumn,intnum_SpecialRow,intnum_SpecialColumn,intboardSize){//棋盘大小为1则直接返回if(boardSize ==1)return;intnum = ++num_Now,//L型骨牌编号
size = boardSize /2;//分割棋盘,行列各一分为二//覆盖左上角子棋盘
if(num_SpecialRow 《 num_BoardTopLeftRow + size && num_SpecialColumn 《 num_BoardTopLeftColumn + size){//递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, size);}else{//用编号为num的L型骨牌覆盖右下角
board[num_BoardTopLeftRow + size -1][num_BoardTopLeftColumn + size -1] = num;//递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_BoardTopLeftRow + size -1, num_BoardTopLeftColumn + size -1, size);}//覆盖右上角子棋盘
if(num_SpecialRow 《 num_BoardTopLeftRow + size && num_SpecialColumn 》= num_BoardTopLeftColumn + size){//递归覆盖含有特殊方格的子棋盘ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn + size, num_SpecialRow, num_SpecialColumn, size);}else{//用编号为num的L型骨牌覆盖左下角
board[num_BoardTopLeftRow + size -1][num_BoardTopLeftColumn + size] = num;//递归覆盖其余棋盘ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn + size, num_BoardTopLeftRow + size -1, num_BoardTopLeftColumn + size, size);}//覆盖左下角子棋盘
if(num_SpecialRow 》= num_BoardTopLeftRow + size && num_SpecialColumn 《 num_BoardTopLeftColumn + size){//递归覆盖含有特殊方格的子棋盘ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, size);}else{//用编号为num的L型骨牌覆盖右上角
board[num_BoardTopLeftRow + size][num_BoardTopLeftColumn + size -1] = num;//递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn, num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size -1, size);}//覆盖右下角子棋盘
if(num_SpecialRow 》= num_BoardTopLeftRow + size && num_SpecialColumn 》= num_BoardTopLeftColumn + size){//递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, num_SpecialRow, num_SpecialColumn, size);}else{//用编号为num的L型骨牌覆盖左上角
board[num_BoardTopLeftRow + size][num_BoardTopLeftColumn + size] = num;//递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, size);}}
今天的分享就到这里了,大家要好好学C++哟~
责任编辑:haq
全部0条评论
快来发表一下你的评论吧 !