棋盘覆盖问题

有一个2^k*2^k的方格棋盘, 恰有一个方格是黑色的, 其它为白色.用包含3个方格的L形牌覆盖所有白色方格.黑色方格不能被覆盖,且白色方格不能被两个或更多的牌覆盖.

[分析] 由2^k*2^k很容易想到分治, 考虑用递归来解决.

我的代码:

#define SIZE 16

char M[SIZE][SIZE];
int P[2];
char Color[4] = {'+','-','~','.'};


/*

  + --- 0
+ +

+ + --- 1
  + 

+   --- 2
+ + 

+ + --- 3
+ 

*/

bool containsPoint( int x, int y,  int px, int py, int size) {
    if (( x <= px ) && ( px < x + size ) &&  ( y <= py ) && ( py < y + size )) return true;
    return false;
}

void Partation(int x, int y, int size, int direction) {
    int s = size/2;
    if ( containsPoint(x,y,P[0],P[1],size) ) {
        direction = 2*((P[0]-x)/s) + (P[1]-y)/s;
    }

    // 递归边界
    if ( size == 2 ) {
        for(int i = 0; i < 2; i++){
            for ( int j = 0; j < 2; j++ ) {
                if (((i+x)==P[0]) && ((j+y)==P[1])) { M[i+x][j+y] = '?'; continue; }
                M[i+x][j+y] = Color[direction];
            }
        }
        return;
    }

    // 分治(右下-左下-右上-左上)
    int drcs[] = {0,1,2,3};
    drcs[3- direction] = direction;
    Partation(x+s,y+s,s,drcs[0]);
    Partation(x+s,y,s,drcs[1]);
    Partation(x,y+s,s,drcs[2]);
    Partation(x,y,s,drcs[3]);


    // 填充空白拐角
    for(int i = 0; i < 2; i++){
        for ( int j = 0; j < 2; j++ ) {
            if ( (2*i + j) == direction ) continue;
            M[x + i + s - 1][y + j + s - 1] = 'o';
        }
    }
}


int main() {
    while (scanf("%d%d",&P[0],&P[1])==2) {
        Partation(0,0, SIZE, 0);
        for ( int i = 0; i < SIZE; i++ ) {
            for ( int j = 0; j < SIZE; j++ ) {
                printf("%c ", M[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

运行结果:

posted @ 2012-12-13 12:57  tsubasa_wp  阅读(204)  评论(0编辑  收藏  举报