C++经典算法问题:棋盘覆盖问题(分治算法)!含源码示例

Posted 一起学编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++经典算法问题:棋盘覆盖问题(分治算法)!含源码示例相关的知识,希望对你有一定的参考价值。

棋盘覆盖问题

问题说明

在一个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值是否大于0

if(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];

}

//为特殊方格赋初值0

board[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] <<"\\t";

}

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++哟~

写在最后:对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

C语言C++编程学习交流圈子,QQ群:904329806点击进入】微信公众号:C语言编程学习基地

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

编程学习书籍分享:

 编程学习视频分享:

 

以上是关于C++经典算法问题:棋盘覆盖问题(分治算法)!含源码示例的主要内容,如果未能解决你的问题,请参考以下文章

分治算法经典案例 - 棋盘问题

分治算法----棋盘覆盖问题

算法复习_分治算法之二分搜索棋盘覆盖快速排序

js算法:分治法-棋盘覆盖

数据结构与算法——分治算法

经典分治之棋盘覆盖问题