棋盤覆蓋(遞迴的應用)
阿新 • • 發佈:2019-01-26
當k>0時,將2k×2k棋盤分割為4個2k-1×2k-1子棋盤(a)所示。
特殊方格必位於4個較小子棋盤之一中,其餘3個子棋盤中無特殊方格。為了將這3個無特殊方格的子棋盤轉化為特殊棋盤,可以用一個L型骨牌覆蓋這3個較小棋盤的會合處,如 (b)所示,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞迴地使用這種分割,直至棋盤簡化為棋盤1×1。
#include<iostream> using namespace std; int tile=1;//骨牌編號 int board[100][100];//棋盤 /*tr棋盤左上角行號 tc棋盤左上角列號 dr當前特殊方格行號 dc當前特殊方格列號 */ 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,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 size; cout<<"輸入棋盤大小:"<<endl; cin>>size; int a,b; cout<<"輸入特殊方格的座標:"<<endl; cin>>a>>b; chessboard(0,0,a,b,size); for(int i=0;i<size;i++) { for(int j=0;j<size;j++) cout<<board[i][j]<<"\t"; cout<<endl; } return 0; }