棋盤覆蓋問題
在一個2^k * 2k(k為正整數,k<=10,length=2k)個方格組成的棋盤中,恰有一個方格與其他方格不同,稱該方格為一特殊方格(其座標為aa,bb,分別代表行座標號和列座標號),以及有四種L型骨牌(如下圖)。求用若干塊這種L型骨牌實現除該特殊點棋盤的全覆蓋。(本題要求採用分治演算法做)
輸入格式:
輸入三個數,分別是aa,bb,length.
輸出格式:
輸出整個棋盤。其中特殊方格填為0,然後鋪棋盤的順序為:先鋪四個子棋盤交界的部分,然後遞迴的對每個子棋盤按照左上,右上,右下,左下的順時針順序鋪滿棋盤。每一塊骨牌中三個方格數字相同,按照順序標號,即第一塊骨牌全標為1,第二塊骨牌全標為2,…,以此類推。輸出的每個數佔4個場寬,右對齊。
輸入樣例:
1 1 4
表示:特殊格子為(1,1),棋盤有4行4列。
輸出樣例:
0 2 3 3
2 2 1 3
5 1 1 4
5 5 4 4
表示:先鋪三個1(一塊L型骨牌),再鋪三個2,…,最後鋪三個5.
分治的技巧在於如何劃分棋盤,使劃分後的子棋盤的大小相同,並且每個子棋盤均包含一個特殊方格,從而將原問題分解為規模較小的棋盤覆蓋問題。k>0時,可將2k×2k的棋盤劃分為4個2(k-1)×2(k-1)的子棋盤。這樣劃分後,由於原棋盤只有一個特殊方格,所以,這4個子棋盤中只有一個子棋盤包含該特殊方格,其餘3個子棋盤中沒有特殊方格。為了將這3個沒有特殊方格的子棋盤轉化為特殊棋盤,以便採用遞迴方法求解,可以用一個L型骨牌覆蓋這3個較小棋盤的會合處,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞迴地使用這種劃分策略,直至將棋盤分割為1×1的子棋盤。
演算法設計:
(1)用一個二維陣列board[size][size]表示一個棋盤,其中,size=2^k。陣列board設為全域性變數;
(2)子棋盤由棋盤左上角的下標tr、tc和棋盤大小s表示;
(3)特殊方格用board[dr][dc]表示特殊方格,dr和dc是該特殊方格在二維陣列board中的下標;
(4) L型骨牌:一個2k×2k的棋盤中有一個特殊方格,所以,用到L型骨牌的個數為(4^k-1)/3,將所有L型骨牌從1開始連續編號,用一個全域性變數tile表示。
(5)每次判斷特殊方塊的位置,遞迴呼叫程式,並不斷新增方塊。
(6)左上的子棋盤(若不存在特殊方格)----則將該子棋盤右下角的那個方格假設為特殊方格;右上的子棋盤(若不存在特殊方格)----則將該子棋盤左下角的那個方格假設為特殊方格;左下的子棋盤(若不存在特殊方格)----則將該子棋盤右上角的那個方格假設為特殊方格;右下的子棋盤(若不存在特殊方格)----則將該子棋盤左上角的那個方格假設為特殊方格
程式碼:
#include<iostream>
using namespace std;
#define N 90
int board[N][N];
int tile=1;
void chessboard(int tr,int tc,int dr,int dc,int size)
{
if(size==1)
return;
int t=tile++;
int s=size/2;
if(dr<tr+s&&dc<tc+s)
chessboard(tr,tc,dr,dc,s);
else
{
board[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
{
board[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+s,dr,dc,s);
else
{
board[tr+s][tc+s]=t;
chessboard(tr+s,tc+s,tr+s,tc+s,s);
} if(dr>=tr+s&&dc<tc+s)
chessboard(tr+s,tc,dr,dc,s);
else
{
board[tr+s][tc+s-1]=t;
chessboard(tr+s,tc,tr+s,tc+s-1,s);
}
}
int main()
{
int aa,bb,length;
cin>>aa>>bb>>length;
chessboard(1,1,aa,bb,length+1);
int i,j;
for(i=1;i<=length;i++)
{
for(j=1;j<=length;j++)
printf("%4d",board[i][j]);
cout<<endl;
}
}
相關文章
- 棋盤覆蓋
- 分治演算法-求解棋盤覆蓋問題演算法
- 棋盤問題
- 棋盤完美覆蓋數(小規模原理實現)
- 線段覆蓋問題
- 棋盤問題 POJ - 1321
- 【離散優化】覆蓋問題優化
- poj 1321 棋盤問題 回溯 JavaJava
- POJ1321棋盤問題(DFS)
- ssh問題之覆盤
- firefox覆蓋原來網頁的問題Firefox網頁
- 公園無線覆蓋維護問題
- Luogu P5089 元素週期表 / Codeforces 1012B Chemical table 題解 [ 並查集 ] [ 二分圖 ] [ 圖論建模 ] [ 棋盤覆蓋問題 ]並查集圖論
- Android軟鍵盤彈出,覆蓋h5頁面輸入框問題AndroidH5
- 樹上最小點覆蓋的一類問題
- 如何做線上問題覆盤
- 企業WiFi覆蓋,解決覆蓋四大難題WiFi
- resultMap 和 resultType 的欄位對映覆蓋問題
- [HAOI2007][洛谷P2218]覆蓋問題
- 如何解決倉庫無線覆蓋的問題?
- 2020年10月24日 矩陣覆蓋問題矩陣
- 流浪方舟重點設計問題覆盤
- 使用貪心演算法解決集合覆蓋問題演算法
- 矩形覆蓋
- bzoj1052: [HAOI2007]覆蓋問題(二分+搜尋)
- 覆盤 PHP 經典面試問題解決過程:上臺階問題PHP面試
- 基於程式覆蓋資訊的資料庫核心問題定位工具資料庫
- 洛谷OJ:P2764 最小路徑覆蓋問題(網路流)
- 【問題覆盤】在Ubuntu 20.04下安裝OFED驅動Ubuntu
- 一次線上OOM問題的個人覆盤OOM
- 【完虐演算法】LeetCode 接雨水問題,全覆盤演算法LeetCode
- 前端技術分享:頁面效能優化問題覆盤前端優化
- 最小圓覆蓋
- Mysql索引覆蓋MySql索引
- 程式碼覆蓋率與測試覆蓋率比較
- 怎樣解題|題3.2.14:填充國際象棋棋盤
- I. 棋盤
- 棋盤 K皇后