棋盘覆盖问题
- 问题叙述
在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
图示:
实例:
2. 基本思路:
关注的重点是特殊方格,2k2k的棋盘上如果没有特殊点,那么L型骨牌不可能完全覆盖,那么我们分治的思路是,每一个父棋盘分解为4个相同大小的子棋盘,除了本身就有特殊点的一个子棋盘,为另外三个棋盘人工设置3个特殊点,以此满足递归条件;基本情况是11棋盘,直接返回。
- 算法
//tr,tc为当前棋盘的左上角行号列号,dr,dc为特殊点行号列号,size是大小
CHSEEBOARD (tr, tc, dr, dc, size):
if size==1 return
//tile是一个全局变量,它不满足递归,用于对人工设置的三个特殊点标记相同的数字
t=++tile
//左上角
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);
//左下角
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 dr<tr+s && dc>=tc+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+s, dr, dc, s)
else
board[tr+s-1][tc+s-1] = t;
CHESSBOARD (tr+s, tc+s, tr+s, tc+s, s);
-
复杂度:O(n^2)
T(1)=1
T(n)=4T(n/2)+1
=>T(n)=O(n^2) -
运行截图
8*8棋盘
-
源代码
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int tile = 0;
void chessBoard(vector<vector<int>> & board,int tr, int tc, int dr, int dc, int size)
{
if(size==1) return;
int t = ++tile;
int s = size/2;
//左上
if(dr<tr+s && dc<tc+s)
chessBoard(board,tr,tc,dr,dc,s);
else
{
board[tr+s-1][tc+s-1] = t;
chessBoard(board,tr,tc,tr+s-1,tc+s-1,s);
}
//左下
if(dr>=tr+s && dc<tc+s)
chessBoard(board,tr+s,tc,dr,dc,s);
else
{
board[tr+s][tc+s-1] = t;
chessBoard(board,tr+s,tc,tr+s,tc+s-1,s);
}
//右上
if(dr<tr+s && dc>=tc+s)
chessBoard(board,tr,tc+s,dr,dc,s);
else
{
board[tr+s-1][tc+s] = t;
chessBoard(board,tr,tc+s,tr+s-1,tc+s,s);
}
//右下
if(dr>=tr+s && dc>=tc+s)
chessBoard(board,tr+s,tc+s,dr,dc,s);
else
{
board[tr+s][tc+s] = t;
chessBoard(board,tr+s,tc+s,tr+s,tc+s,s);
}
}
void Print(const vector<vector<int>> &board)
{
int n= board.size();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<setw(2)<<left<<board[i][j]<<" ";
}
cout<<endl;
}
}
int main(int argc, char** argv) {
vector<vector<int>> board;
board.resize(8);
for(int i=0;i<board.size();i++)
{
board[i].resize(8);
}
board[3][3] = 0;
chessBoard(board,0,0,3,3,board.size());
Print(board);
return 0;
}
注:文章中的示例及L型骨牌图片来自于
https://blog.csdn.net/yew1eb/article/details/8776985