棋盤覆蓋問題是指在乙個n*n(n=2k,k>0)的棋盤上給定任意乙個特殊點,用l型條塊覆蓋棋盤中除特殊點外的所有方格。每個l型條塊可以任意旋轉,恰好覆蓋3 個方格。如n=4的棋盤覆蓋方案如圖(a)所示,其中黑色點表示特殊點,l型覆蓋用不同顏色區分。
棋盤覆蓋的解決方案是分治法。
(1)將2k*2k棋盤均勻分成4個子棋盤,分別為左上角子棋盤、右上角子棋盤、左下角子棋盤、右下角子棋盤,大小為2k-1*2k-1,如圖(b)所示。
(2)如果該特殊點在某一子棋盤,則用乙個l型覆蓋其它三個子棋盤與其相交的部分,使剩餘三個子棋盤也成為含特殊點的子棋盤。如圖(c),特殊點在左上角子棋盤,則l型覆蓋如圖(c)所示。此過程的處理過程如下:
左上角子棋盤若不存在特殊方格,則將該子棋盤右下角的那個方格假設為特殊方格;
右上角子棋盤若不存在特殊方格,則將該子棋盤左下角的那個方格假設為特殊方格;
左下角子棋盤若不存在特殊方格,則將該子棋盤右上角的那個方格假設為特殊方格;
右下角子棋盤若不存在特殊方格,則將該子棋盤左上角的那個方格假設為特殊方格;
過程(2)的l型條塊覆蓋後,4個子棋盤均變為含特殊點的棋盤,對這4部分遞迴進行l型覆蓋,直至全覆蓋即找到棋盤覆蓋的解決方案。假設遞迴順序是左上角子棋盤、右上角子棋盤、左下角子棋盤、右下角子棋盤。
程式設計實現棋盤覆蓋,輸出遞迴過程中l型覆蓋的順序號,特殊點用0表示。如n=4,輸出
2 0 3 3
2 2 1 3
4 1 1 5
4 4 5 5
三個1是第一次l型覆蓋。遞迴對左上角子棋盤覆蓋,實現第2個l型覆蓋,設定3個2;同理,對右上角子棋盤覆蓋,設定3個3;對左下角子棋盤覆蓋,設定3個4;對右下角子棋盤覆蓋,設定3個5。
n=8的輸出見樣例,請自行分析其覆蓋順序,理解棋盤覆蓋的遞迴。
測試次數t
每組測試資料一行,格式為:
棋盤大小n(2k,k>0) 特殊點的行、列座標 (從1到n)
對每組測試資料,輸出n*n的二維陣列,陣列中的數字表示l型條框的覆蓋順序,特殊點位置輸出0。
輸出格式為:每行前n-1個數字佔4位,左對齊。每行最後乙個數字直接輸出,後無空格。不同組資料輸出之間有空行。
32 1 1
4 2 4
8 6 6
0 1
1 1
2 2 3 3
2 1 3 0
4 1 1 5
4 4 5 5
3 3 4 4 8 8 9 9
3 2 2 4 8 7 7 9
5 2 6 6 10 10 7 11
5 5 6 1 1 10 11 11
13 13 14 1 18 18 19 19
13 12 14 14 18 0 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21
其實原理就是不斷得細分格仔,從左到右,從右到左下。。。
**實現:
#include
using namespace std;
int p[100][100];
int num;
//lx,ly是左上角的方格座標 sx,sy是特殊點的方格座標
void pai(int length,int lx,int ly,int sx,int sy)
//覆蓋右上角
if(sx=ly+s)
pai(s,lx,ly+s,sx,sy);//然後再把這個方格分成更小的方格
else
//覆蓋左下角
if(sx>=lx+s&&sypai(s,lx+s,ly,sx,sy);
else
//覆蓋右下角
if(sx>=lx+s&&sy>=ly+s)
pai(s,lx+s,ly+s,sx,sy);
else }
int main()
cout
cout
return 0;
}
mallco動態分配 malloc動態分配多維陣列
下面試自己寫的三個測試程式,如果看懂了基本上動態分配多維陣列就沒什麼問題啦 重點 1 深刻理解多維陣列的概念,多維陣列在記憶體中的分配情況,基本上動態分配也沒什麼問題的。然後還要注意一點的就是,釋放是分配的逆過程!include include include void main void int ...
遞迴 棋盤覆蓋
問題描述 在乙個2 k 2 k 的方格組成的棋盤中,有乙個方格與其他方格不同,稱為特殊方格。現在邀請4中不同的l型骨牌 覆蓋給定的棋盤除特殊方格外的所有方格。例如 這是乙個k 2時的棋盤,特殊點座標為 0,1 四中l型骨牌如圖 程式 include define key 8 棋盤的階數 int ar...
記憶體動態分配
陣列的元素儲存於記憶體中連續的位置上。當乙個陣列被宣告時,它所需要的內存在編譯時就被分配。但是,你也可以使用動態記憶體分配在執行時為它分配記憶體。malloc所分配的是一塊連續的記憶體。例如,如果請求它分配100個位元組的記憶體,那麼它實際分配的記憶體就是100個連續的位元組,並不會分開位於兩塊或多...