1. 程式人生 > 其它 >分治與遞迴--棋盤覆蓋問題

分治與遞迴--棋盤覆蓋問題

題目描述

在一個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;
}