分治與遞迴--棋盤覆蓋問題
阿新 • • 發佈:2022-05-22
題目描述
在一個2k×2k個方格組成的棋盤中,恰有一個方格與其它方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。
在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。
參考輸入、輸出:
輸入:輸入第一行包括一個整數k,第二行兩個整數x,y代表特殊點座標(從1開始)。
輸出:輸出一個2k×2k的矩陣代表結果,0表示特殊點。
Simple input:
2
1 2
Simple output:
2 0 3 3
2 2 1 3
4 1 1 5
4 4 5 5
題目思路
- 每次將棋盤一分為四,在沒有特殊方格
題目程式碼
#include <iostream> #include <cmath> using namespace std; const int N = 110; int tile = 0; int Board[N][N]; /* 引數說明: tr:棋盤左上角方格的行號 tc:棋盤左上角方格的列號 dr:特殊方格所在的行號 dc:特殊方格所在的列號 size:棋盤的長度 */ void ChessBoard(int tr, int tc, int dr, int dc, int size) { if(size == 1) return; int t = ++ tile; // L型骨牌號 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; // 用 t號 L型骨牌覆蓋右下角 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; // 用 t號 L型骨牌覆蓋左下角 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 k, x, y, size; cin >> k >> x >> y; size = (int)pow(2, k); ChessBoard(1, 1, x, y, size); for(int i = 1; i <= size; i ++ ) { for(int j = 1; j <= size; j ++ ) cout << Board[i][j] << " "; puts(""); } return 0; }