殘缺棋盤問題的思路是分治法。首先分成四個象限,在沒有殘缺的三部分中間添加一塊三格板,再分割,再添格板……
很明顯應該用遞歸來解決這個問題。
分四個象限四種情況:
//分治法 遞歸
void TileBoard(int fr, int fc, int dr, int dc, int size) {
//fr fc爲左上角第一個格子橫縱座標,dr dc爲殘缺格橫縱座標,size爲邊長,是2^n
if (size == 1) //判斷遞歸結束條件爲邊長爲一,不可再繼續分割,則返回
return;
int t = ++tile; //分隔板計數
int s = size / 2; //分割行爲
//左上
if (dr < fr + s && dc < fc + s) { //殘缺點橫縱座標都不超過棋盤一半,在第一象限,直接分割
TileBoard(fr, fc, dr, dc, s);
}
else { //殘缺點不在第一象限
Board[fr + s - 1][fc + s - 1] = t; //標記右下角
TileBoard(fr, fc, fr + s - 1, fc + s - 1, s); //繼續分割
}
//右上
if (dr < fr + s && dc >= fc + s) { //殘缺點在第二象限,直接分割
TileBoard(fr, fc + s, dr, dc, s);
}
else { //殘缺點不在第二象限
Board[fr + s - 1][fc + s] = t; //標記左下角
TileBoard(fr, fc + s, fr + s - 1, fc + s, s); //繼續分割
}
//左下
if (dr >= fr + s && dc < fc + s) { //殘缺點在第三象限,直接分割
TileBoard(fr + s, fc, dr, dc, s);
}
else { //殘缺點不在第三象限
Board[fr + s][fc + s - 1] = t; //標記右上角
TileBoard(fr + s, fc, fr + s, fc + s - 1, s); //繼續分割
}
//右下
if (dr >= fr + s && dc >= fc + s) { //殘缺點在第四象限,直接分割
TileBoard(fr + s, fc + s, dr, dc, s);
}
else { //殘缺點不在第四象限
Board[fr + s][fc + s] = t; //標記左上角
TileBoard(fr + s, fc + s, fr + s, fc + s, s); //繼續分割
}
}