在一个2k×2k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘,显然特殊方格在棋盘上出现的位置有4k种情形。因而对任何k>=0,有4k种不同的特殊棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的回合处,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为1X1棋盘。
实现这种分治策略的算法chessBoard可实现如下:
public void chessBoard(int tr, int tc, int dr, int dc, int size)
{
if(size==1) return;
int t=tile++, //L型骨牌号
s=size/2; //分割棋盘
//覆盖左上角子棋盘
if(dr<tr+s&&dc<tc+s)
//特殊方格在此棋盘中
chessBoard(tr,tc,dr,dc,s);
else{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖右下角
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{//此棋盘中无特殊方格
//用t号L型骨牌覆盖左下角
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{//用t号L型骨牌覆盖右上角
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{//用t号L型骨牌覆盖左上角
board[tr+s][tc+s]=t;
//覆盖其余方格
chessBoard(tr+s,tc+s.tr+s,tc+s,s);
}
}
其中 tr:棋盘左上角方格的行号;tc:棋盘左上角方格的列号;dr: 特殊方格所在的行号;dc:特殊方格所在的列号;size: 2k,棋盘规格为2k×2k