您的位置:首页 > 其它

算法07:棋盘覆盖——分治法Part3

2014-04-28 17:28 197 查看
(3)棋盘覆盖

在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。



分治法的思想:当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。 



具体算法:

(1)将棋盘分为4部分,检查特殊方格是否在左上部分

          a.在,继续将左上部分分割;

          b.不在,将这部分右下角的格子填充,作为特殊方格,继续分割;

(2)将左下角、右上角、右下角按同样的方式处理

(3)递归棋盘为1*1时结束

完整算法

#include <cstdlib>
#include <iostream>

using namespace std;

int board[100][100];
int t0 = 0;

void chess_board(int dx, int dy, int tx, int ty, int size )
{
if(size == 1) return;

int t = ++t0;

int s = size/2;

//检查特殊格是否在左上部分
if(tx < dx+s && ty < dy+s) {
chess_board(dx, dy, tx, ty, s);
}
else{//不在右下角填充
board[dx+s-1][dy+s-1] = t;
chess_board(dx, dy, dx+s-1, dy+s-1, s);
}
//检查特殊格是否在左下部分
if(tx >= dx+s && ty < dy+s) {
chess_board(dx+s, dy, tx, ty, s);
}
else{//不在右上角填充
board[dx+s][dy+s-1] = t;
chess_board(dx+s, dy, dx+s, dy+s-1, s);
}
//检查特殊格是否在右上部分
if(tx < dx+s && ty >= dy+s) {
chess_board(dx, dy+s, tx, ty, s);
}
else{//不在左下角填充
board[dx+s-1][dy+s] = t;
chess_board(dx, dy+s, dx+s-1, dy+s, s);
}
//检查特殊格是否在右下部分
if(tx >= dx+s && ty >= dy+s) {
chess_board(dx+s, dy+s, tx, ty, s) ;
}
else{//不在左上角填充
board[dx+s][dy+s] = t;
chess_board(dx+s, dy+s, dx+s, dy+s, s);
}
}

int main()
{
int size, x, y;

while(cin>>size>>x>>y){

chess_board(0, 0, x, y, size);

for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
cout<<board[i][j]<<" ";
}
cout<<endl;
}
}

system("PAUSE");
return 0;
}

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息