棋盤覆蓋問題

2021-08-10 04:29:28 字數 1855 閱讀 8509

實驗目的:熟悉掌握分治演算法設計技術

棋盤大小: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...