算法设计与分析之分治法——棋盘覆盖

来源:互联网 发布:西门子编程电缆有几种 编辑:程序博客网 时间:2024/06/06 02:05

一:算法分析

棋盘覆盖问题要求在2^k * 2^k 个方格组成的棋盘中,你给定任意一个特殊点,用一种方案实现对除该特殊点的棋盘实现全覆盖。

建立模型如图:

解决方案就是利用分治法,将方形棋盘分成4部分,如果该特殊点在某一部分,我们就去递归他,如果不在某一部分,我们假设一个点为特殊点,同样递归下去,知道全覆盖。

    左上角的子棋盘(若不存在特殊方格):则将该子棋盘右下角的那个方格假设为特殊方格;

    右上角的子棋盘(若不存在特殊方格):则将该子棋盘左下角的那个方格假设为特殊方格;

    左下角的子棋盘(若不存在特殊方格):则将该子棋盘右上角的那个方格假设为特殊方格;

    右下角的子棋盘(若不存在特殊方格):则将该子棋盘左上角的那个方格假设为特殊方格;

#include <iostream>#include <cstring>#include <cstdio>using namespace std;//tr表示棋盘左上角行号//tc表示棋盘左上角列号//dr表示特殊棋盘的行号//dc表示特殊棋盘的列号//size = 2^k//棋盘的规格为2^k * 2^kconst int SIZE = 8;static int tt = 1;static int board[SIZE][SIZE];void ChessBoard(int tr,int tc,int dr,int dc,int size){    if(size == 1)//棋盘只有一个方格且是特殊方格        return ;    int t = tt++; //L型骨牌号    int s = size>>1;//分割棋盘     //覆盖左上角子棋盘    if(dr<tr+s&&dc<tc+s)        ChessBoard(tr,tc,dr,dc,s); //特殊方格在此棋盘中    else    {         //此棋盘无特殊方格         //用t号L型骨牌覆盖右下角        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    {         //此子棋盘中无特殊方格         //用t号L型骨牌覆盖左下角        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     {         //用t号L型骨牌覆盖右上角         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     {         //用t号L型骨牌覆盖左上角         board[tr + s][tc + s] = t;         //覆盖其余方格         ChessBoard(tr + s, tc + s, tr + s, tc + s, s);     }}void ChessPrint(){    for(int i = 0; i < SIZE; i++)    {        for(int j = 0; j < SIZE; j++)        {            cout.width(3);            cout<<board[i][j]<<" ";        }       cout<<endl;    }}int main(){    int x,y;    cin>>x>>y;    ChessBoard(0,0,x,y,SIZE);    ChessPrint();    return 0;}

0 0