棋盘覆盖问题
有一个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; }
运行结果: