五大常用算法(一) 分治算法(4) 棋盘覆盖

转载自:http://bingxinye1.blog.163.com/blog/static/1687970982010910103023578/

在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。

    四各L型骨牌如下图1
棋盘覆盖问题 - 蔷薇阁 - 落落工作室
 
      图1  
棋盘中的特殊方格如图2
棋盘覆盖问题 - 蔷薇阁 - 落落工作室
 
图2
    实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。以上原理如图3所示。
棋盘覆盖问题 - 蔷薇阁 - 落落工作室
图3
 
代码:
#include<iostream>
using namespace std;
const int Max=1000;
int board_size;
int board[Max][Max];
 
//row是大棋盘左上角的横坐标
//col是大棋盘左上角的竖坐标
//r,c分别为黑格子的横竖坐标
void chessboard(int row,int col,int r,int c,int size)
{
 if(size==1)
  return;
 static int board_number=1;
 int d;
 d=board_number++;
 int half_size=size/2;
 
 if(r<half_size+row&&c<half_size+col)//特殊方格在左上角子棋盘
 {
  chessboard(row,col,r,c,half_size);
 }
 else// 不在此棋盘,将此棋盘右下角设为相应的骨牌号
 {
  board[row+half_size-1][col+half_size-1]=d;  //
  chessboard(row,col,row+half_size-1,col+half_size-1,half_size);
 }
 if(r<row+half_size&&c>=col+half_size)特殊方格在右上角子棋盘
 {
  chessboard(row,col+half_size,r,c,half_size);
 }
 else
 {
  board[row+half_size-1][col+half_size]=d;
  chessboard(row,col+half_size,row+half_size-1,col+half_size,half_size);
 }
 if(r>=row+half_size&&c<col+half_size)//特殊方格在左下角子棋盘
 {
  chessboard(row+half_size,col,r,c,half_size);
 }
 else
 {
  board[row+half_size][col+half_size-1]=d;
  chessboard(row+half_size,col,row+half_size,col+half_size-1,half_size);
 }
 if(r>=row+half_size&&c>=col+half_size)//特殊方格在右下角子棋盘
 {
  chessboard(row+half_size,col+half_size,r,c,half_size);
 }
 else
 {
  board[row+half_size][col+half_size]=d;
  chessboard(row+half_size,col+half_size,row+half_size,col+half_size,half_size);
 }
}
void print(int k)
{
 for(int i=0;i<k*2;i++)
 {
  for(int j=0;j<2*k;j++)
  {
   cout<<board[i][j]<<" ";
  }
  cout<<endl;
 }
}
int main()
{
 int k;
 cout<<"请输入棋盘的个数:"<<endl;
 cin>>k;
 int r,c;
 cout<<"请输入是黑色格子的位置:"<<endl;
 cin>>r>>c;
 board[r][c]=0;
 chessboard(0,0,r,c,k*2);
 print(k);
 return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值