分治算法--棋盤覆蓋


 

問題描述

在一個2^k×2^k 個方格組成的棋盤中,恰有一個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

解題思路

分析:當k>0時,將2k×2k棋盤分割為4個2^k-1×2^k-1 子棋盤(a)所示。特殊方格必位於4個較小子棋盤之一中,其余3個子棋盤中無特殊方格。為了將這3個無特殊方格的子棋盤轉化為特殊棋盤,可以用一個L型骨牌覆蓋這3個較小棋盤的會合處,如 (b)所示,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞歸地使用這種分割,直至棋盤簡化為棋盤1×1。(出自算法設計與分析-王曉東)

實現:每次都對分割后的四個小方塊進行判斷,判斷特殊方格是否在里面。這里的判斷的方法是每次先記錄下整個大方塊的左上角(top left coner)方格的行列坐標,然后再與特殊方格坐標進行比較,就可以知道特殊方格是否在該塊中。如果特殊方塊在里面,這直接遞歸下去求即可,如果不在,這根據分割的四個方塊的不同位置,把右下角、左下角、右上角或者左上角的方格標記為特殊方塊,然后繼續遞歸。在遞歸函數里,還要有一個變量s來記錄邊的方格數,每次對方塊進行划分時,邊的方格數都會減半,這個變量是為了方便判斷特殊方格的位置。其次還要有一個變nCount來記錄L型骨牌的數量。

代碼實現:

#include <stdio.h>
#include <stdlib.h>

int nCount = 0;
int Matrix[100][100];

void chessBoard(int tr, int tc, int dr, int dc, int size);

int main()
{
    int size,r,c,row,col;
    memset(Matrix,0,sizeof(Matrix));
    scanf("%d",&size);
    scanf("%d%d",&row,&col);
    chessBoard(0,0,row,col,size);

    for (r = 0; r < size; r++)
    {
        for (c = 0; c < size; c++)
        {
            printf("%2d ",Matrix[r][c]);
        }
        printf("\n");
    }

    return 0;
}

void chessBoard(int tr, int tc, int dr, int dc, int size)
{
    //tr and tc represent the top left corner's coordinate of the matrix
    int s,t;
    if (1 == size) return;

    s = size/2; //The number of grid the matrix's edge
    t = ++ nCount;

    //locate the special  grid on bottom right corner
    if (dr < tr + s && dc < tc +s)
    {
        chessBoard(tr,tc,dr,dc,s);
    }
    else
    {
        Matrix[tr+s-1][tc+s-1] = t;
        chessBoard(tr,tc,tr+s-1,tc+s-1,s);
    }

    //locate the special  grid on bottom left corner
    if (dr < tr + s && dc >= tc + s )
    {
        chessBoard(tr,tc+s,dr,dc,s);
    }
    else
    {
        Matrix[tr+s-1][tc+s] = t;
        chessBoard(tr,tc+s,tr+s-1,tc+s,s);
    }

    //locate the special  grid on top right corner
    if (dr >= tr + s && dc < tc + s)
    {
        chessBoard(tr+s,tc,dr,dc,s);
    } 
    else
    {
        Matrix[tr+s][tc+s-1] = t;
        chessBoard(tr+s,tc,tr+s,tc+s-1,s);
    }

    //locate the special  grid on top left corner
    if (dr >= tr + s && dc >= tc + s)
    {
        chessBoard(tr+s,tc+s,dr,dc,s);
    } 
    else
    {
        Matrix[tr+s][tc+s] = t;
        chessBoard(tr+s,tc+s,tr+s,tc+s,s);
    }

}
2013/6/14 22:30

 

程序結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM