ChessBoard棋盘覆盖问题

             棋盘覆盖问题是一个经典的分治问题的算法,它其中的思想,就是分而治之。

         怎么体现分而治之的思想是这个问题的关键。

         首先,将棋盘分为四个小的方块,体现了分,但是却破坏了问题的统一性,因为小的方块中,三个块中没有特殊的方块。

        所以为了不破坏分而不乱的思想,我们可以在每一个小块中加一个特殊的小方块,但是加一个小方块,随便填的话,同样还是破坏了分的目的,故,书本上给出了一种比较高明的技巧,在没有特殊块的方块中,将一个L型的块放到三个块的交界处,一来,这是一种往棋盘填块的方式,不破坏题意的目的,二来,又增加了其他三个无特殊块的方格,三个特殊方格。可谓是一举两得,这样使得分开之后的问题与原问题是一样的,只有这样才可以用分治法来处理。

    下面上代码同样的,使用了c++代码

         

//棋盘覆盖 
#include<iostream>
#include<cstring>
#include<cstdlib>
#define SIZE 8
using namespace std;
int Board[SIZE][SIZE];//棋盘坐标 
int kind;             //放置牌的种类 
void ChessBoard(int tr,int tc,int dr,int dc,int size){
    if(size==1)return;
    int t=kind++;
    int s=size/2;
    // 从左上角的方块开始检查 
    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,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,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+s,tc+s,dr,dc,s);
    else{
        Board[tr+s][tc+s]=t;
        ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
        }
    }
    
int main(){
    memset(Board,0,sizeof(Board));//棋盘初始化为0 
    cout<<"Initnation the Board!The curent sutation is:"<<endl;
    for(int i = 0;i < SIZE;i ++){
        for(int j = 0;j < SIZE;j ++)
        cout<<Board[i][j]<<" ";
        cout<<endl;
        }                          //打印当前的棋盘状态 
    cout<<"The chessboard is covered..."<<endl;
    ChessBoard(0,0,0,3,SIZE);       //开始放置 
    cout<<"The chessboard is:"<<endl;
    cout.fill('0');                 //用0填充空白 
    for(int i = 0;i < SIZE;i ++){
        for(int j = 0;j < SIZE;j ++){
        cout.width(2);              //便于查看控制字符为两个空白的宽度 
        cout<<Board[i][j]<<" ";
        }
        cout<<endl;
        }
        system("pause");
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值