棋盤覆蓋問題的遞歸解決

具體的題目是:
有一個 的方格棋盤,恰有一個方格是黑色的,其它爲白色。你的任務是用包含3個方格的L型牌覆蓋所有白色方格。黑方格不能被覆蓋,且任意一個白色方格不能同時被兩個或者多個L型牌覆蓋。如圖爲L型牌的4種旋轉方式。
4種方式

問題分析:
我們很容易想到用遞歸的方法去解決這個問題,在經典的遞歸問題漢諾塔問題中我們,把N個盤子的問題分解成N-1個問題去遞歸解決。那麼我們也可以往這方面想,這個棋盤規格是2^k*2^K,那麼我們可以將k減去1,將大棋盤分成小棋盤來解決。於是大棋盤被分成了四個小棋盤,可是新的問題來了,雖然把棋盤分解了可是隻有一個棋盤裏是有黑塊的,這樣沒法進行遞歸。既然沒有那麼我們就想辦法給它添上,而且每分一次就添一次,保證遞歸的進行。問題的關鍵是怎麼添,添在哪裏?根據這個L形的形狀,可以在分割的中心的添上一個L形。如圖所示:
這裏寫圖片描述
然後遞歸就可以順利的進行了。總結一下過程:

  1. 遞歸的結束條件當:k=0時,也就是不在是一個棋盤的時候,可能會有人問問什麼不是k=1時,因爲k=1時依然需要繼續把另外三個地方添上黑塊。
  2. 遞歸關係,將大棋盤分解爲小棋盤遞歸解決。

好了不說了上代碼:

#include <stdio.h>
#include <stdlib.h>
#include<string.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_s("%d", &size);
    scanf_s("%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)
{
    int s, t;
    if (1 == size) return;
    s = size / 2;
    t = ++nCount;
    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);
    }

    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);
    }
    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);
    }
    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);
    }

}

這是我的一點點理解,有什麼不對的請大家批評指正,歡迎評論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章