算法之棋盤覆蓋

問題描述:棋盤覆蓋問題要求在2^k * 2^k 個方格組成的棋盤中,任意給定一個與其它方格不同的特殊方格,用如圖中4種L型骨牌,實現對除特殊方格外的棋盤實現全覆蓋。

建立模型如圖:

問題分析:用分治策略,如上圖,當k>0時,將棋盤分割成大小相等的4個部分,則特殊方格必然位於其中一部分棋盤內,假設特殊方格位於左上角棋盤內,則挑選如圖L型骨牌覆蓋這3個較小棋盤的會合處,將另外這3個較小棋盤也轉化成含有特殊方格的棋盤。繼續對每個較小棋盤進行遞歸,直到棋盤被分割成1×1棋盤爲止。

#include <iostream>
using namespace std;
//棋盤左上角位置(leftx,lefty),特殊方格位置(dx,dy),棋盤規模length,棋盤chess
void ChessBoard(int leftx,int lefty,int dx,int dy,int length,int chess[8][8])
{
    chess[dx][dy]=1;
    if(length==1){chess[leftx][lefty]=1;return;} //如果棋盤已經被簡化爲1×1棋盤,則結束遞歸。
    int width = length/2;    //棋盤規模

    if(dx<leftx+width&&dy<lefty+width)
    {
        //特殊方格在左上角棋盤裏面
        ChessBoard(leftx,lefty,dx,dy,width,chess);
    }
    else ChessBoard(leftx,lefty,leftx+width-1,lefty+width-1,width,chess);

    if(dx<leftx+width&&dy>=lefty+width)
    {
        //特殊方格在左下角棋盤裏面
        ChessBoard(leftx,lefty+width,dx,dy,width,chess);
    }
    else ChessBoard(leftx,lefty+width,leftx+width-1,lefty+width,width,chess);

    if(dx>=leftx+width&&dy<lefty+width)
    {
        //特殊方格在右上角棋盤裏面
        ChessBoard(leftx+width,lefty,dx,dy,width,chess);
    }
    else ChessBoard(leftx+width,lefty,leftx+width,lefty+width-1,width,chess);

    if(dx>=leftx+width&&dy>=lefty+width)
    {
        //特殊方格在右下角棋盤裏面
        ChessBoard(leftx+width,lefty+width,dx,dy,width,chess);
    }
    else ChessBoard(leftx+width,lefty+width,leftx+width,lefty+width,width,chess);
}


int main()
{
    int chess[8][8],dx=1,dy=2;
    ChessBoard(0,0,1,1,8,chess);
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
            cout<<chess[i][j]<<" ";
        cout<<endl;
    }
}

複雜性分析:分析可知,該算法滿足遞歸方程:T(k)=4T(k-1)+O(1)  (k>0),解此遞歸方程可得T(k)=O(4^k)。


發佈了44 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章