棋盤問題的遞歸解決

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


4種方式
4種方式

問題分析:
我們很容易想到用遞歸的方法去解決這個問題,在經典的遞歸問題漢諾塔問題中我們,把N個盤子的問題分解成N-1個問題去遞歸解決。那么我們也可以往這方面想,這個棋盤規格是2k*2K,那么我們可以將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);
    }

}

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 分治策略 本文包括分治的基本概念二分查找快速排序歸并排序找出偽幣棋盤覆蓋最大子數組 源碼鏈接:https://gi...
    廖少少閱讀 1,903評論 0 7
  • 參考blog 棋盤覆蓋問題 問題描述 在一個2^k * 2^k個方格組成的棋盤中,有一個方格與其它的不同,若使用以...
    chenhh6701閱讀 3,344評論 0 4
  • Tags: 算法 棋盤覆蓋問題 【問題描述】 在一個2^k×2^k個方格組成的棋盤中,若有一個方格與其他方格不同,...
    zhwhong閱讀 6,292評論 4 16
  • 近來越來越喜歡早起,清晨的寧靜讓我的心安寧歡暢。 坐在窗旁,凝視風中的樹葉,不時看見幾只鳥飛過,聽見它們的鳴啾,真...
    周舟閱讀與寫作閱讀 326評論 0 0
  • 夜深, 驚醒, 月光纏上來, 給我透心的冷。 踢不開, 擋不住。 我只剩無助, 無助的看著, 看著月光, 不停的將...
    君兮閱讀 498評論 15 7