題目:有乙個2k∗
2k2^k*2^k
2k∗2
k的方格棋盤,恰有乙個方格是黑色的,其他為白色。你的任務是用包含3個方格的l型牌覆蓋所有白色方格。黑色方格不能被覆蓋,且任意乙個白色方格不能同時被兩個或更多牌覆蓋。
由於棋盤是2k∗
2k2^k*2^k
2k∗2
k的,很容易在中間橫豎各一刀劃分為4個2k−
1∗2k
−12^*2^
2k−1∗2
k−1的小棋盤,繼續劃分一直到k=1,成為2∗2
2*22∗
2的棋盤。如果k=1,且2∗2
2*22∗
2的棋盤上有乙個黑色方塊,那麼可以用一塊l牌覆蓋。
那麼其它的不含黑色方塊的區域呢?當k=2時,棋盤大小為4×4
4×44×
4,其上下左右四個區域有乙個區域有黑色方塊,另外三個沒有。那麼我們可以用一塊l牌覆蓋有黑色方塊的區域,另外三個區域採用下圖的覆蓋方式,能夠留出乙個l型的未覆蓋區域,剛好再用一塊l牌覆蓋。
這樣我們就知道遞迴的基本思路了:將棋盤劃分成四部分,如果:
左上部分沒有黑色方塊,將左上部分右下角設定為特殊方塊(將被圖中紫色l牌覆蓋);
右上部分沒有黑色方塊,將左上部分左下角設定為特殊方塊(將被圖中紫色l牌覆蓋);
左下部分沒有黑色方塊,將左上部分右上角設定為特殊方塊(將被圖中紫色l牌覆蓋);
右下部分沒有黑色方塊,將左上部分左上角設定為特殊方塊(將被圖中紫色l牌覆蓋);
每次遞迴分別檢查上下左右四部分,如果有黑色方塊則繼續遞迴,否則填充特殊方塊。將特殊方塊視為黑色方塊並再次遞迴。當棋盤為2∗2
2*22∗
2時填充完畢,當棋盤為1∗1
1*11∗
1時直接返回(base case)。注意全域性變數count和區域性變數t的使用,count的最終值同時也是使用的l牌塊數。
#include
#include
using
namespace std;
int count =1;
void
print
(vector
int>> s)
}void cover_board (vector< vector<
int>
>
&board,
int size,
int lu_r,
int lu_c,
int black_r,
int black_c)
//black_r和black_c記錄黑色方塊所在行和列。lu_x和lu_y記錄當前棋盤左上角的行和列。
if(black_r >= lu_r + n && black_c < lu_c + n)
//黑色方塊在左下角
cover_board
(board, n, lu_r + n, lu_c, black_r, black_c)
;else
if(black_r < lu_r+n && black_c >= lu_c + n)
//黑色方塊在右上角
cover_board
(board, n, lu_r, lu_c+n, black_r, black_c)
;else
if(black_r >= lu_r+n && black_c >= lu_c + n)
//黑色方塊在右下角
cover_board
(board, n, lu_r+n, lu_c+n, black_r, black_c)
;else
}int
main()
size=8,黑色方塊位於第四排第六列時輸出結果:
size=16,黑色方塊位於第四排第六列時輸出結果:
演算法競賽入門經典(第八章)
習題8 1 uva1149 11.8 include include using namespace std int main sort w 1,w n 1 l 1 r n num 0 while l r if mi w l 0 l num cout 習題8 2 uva1610 11.8 inclu...
演算法入門經典第八章學習筆記(上)
教學內容相關章節 8.1演算法分析初步 8.2再談排序與搜尋 8.3遞迴與分治 8.4貪心法 教學目標 加粗表示基本掌握 1 理解 基本操作 漸近時間複雜度的概念和大o記號的含義 2 掌握 最大連續和 問題的各種演算法及其時間複雜度分析 3 正確認識演算法分析的優點和侷限性,能正確使用分析結果 4 ...
演算法入門經典第八章學習筆記(中)
有乙個2 k 2 k個方格棋盤,恰有乙個方格是灰色的,其他為白色,你的任務是用包含3個方格的l型骨牌覆蓋所有白色方格。灰色方格不能被子覆蓋,且任意乙個白色方格不能同時被兩個或更多骨牌覆蓋。如圖8 3所示為l型骨牌 三格板 的4種旋轉方式。方法也是分治法,總牌數 4 k 1 3 劃分成下面 a 這樣,...