實驗目的:熟悉掌握分治演算法設計技術
棋盤大小:16*16
基本思想、原理和演算法描述:
演算法描述:
當k>0時,可以將2^k *2^k棋盤分割為4個2^k-1 * 2^k-1子棋盤。由棋盤覆蓋問題得知,特殊方格必位於4個較小的子棋盤中,其餘3個子棋盤中無特殊方格。為了將3個無特殊方格的子棋盤轉化為特殊棋盤可以將乙個l型骨牌覆蓋這3個較小棋盤的會合處,所以,這3個子棋盤上被l型覆蓋的方格就成為給棋盤上的特殊方格,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞迴的使用這種分割,直至棋盤簡化為1*1棋盤為止。
棋盤:用乙個二維陣列board[size][size]表示乙個棋盤。
子棋盤:子棋盤由棋盤左上角的下標 tr(棋盤上左上角方格的行號)、tc(棋盤上左上角方格的列號)。
特殊方格:用board[dr][dc]表示特殊方格,dr(行號)和dc(列號)是該特殊方格在二維陣列board中的下標。
l型骨牌:乙個2^k *2^k的棋盤中有乙個特殊方格,所以,用到l型骨牌的個數為(4k-1)/3,將所有l型骨牌從1開始連續編號,用乙個全域性變數tile表示。
程式和結果:
程式:#include
#include
int tile=1; //記錄骨牌的型號
int board[100][100]=; //儲存棋盤被覆蓋的情況
void chessboard(int tr,int tc,int dr,int dc,int size)
{ //tr和tc是棋盤左上角的下標,dr和dc是特殊方格的下標,size是棋盤的大小
int t=0;
int s;
if (size==1)return;
t=tile++;
s=size/2; //劃分棋盤
//覆蓋左上角棋盤
if (drchessboard(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=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&&dcchessboard(tr+s,tc,dr,dc,s);
else
board[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
board[tr+s][tc+s]=t;
chessboard(tr+s,tc+s,tr+s,tc+s,s);
int main()
int k,x,y;
printf("棋盤的規模k:");
scanf("%d",&k);
printf("特殊方格的下標x y:");
scanf("%d %d",&x,&y);
chessboard(0,0,x,y,pow(2,k));
for(int i=0; ifor (int j=0; jprintf("%-4d",board[i][j]);
printf("\n");
return 0;
執行結果:
棋盤覆蓋問題
source code include include include using namespace std const int n 1024 int board n n count void cover int sx,int sy,int cx,int cy,int size,int cx1,i...
棋盤覆蓋問題
問題 在乙個2k 2k k 0 個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為特殊方格。顯然,特殊方格在棋盤中可能出現的位置有4k種,因而有4k種不同的棋盤,圖4.10 a 所示是k 2時16種棋盤中的乙個。棋盤覆蓋問題 chess cover problem 要求用圖4.10 b 所示...
棋盤覆蓋問題
棋盤覆蓋問題 time limit 1000ms,special time limit 2500ms,memory limit 32768kb total submit users 103,accepted users 40 problem 10432 no special judgement pr...