1.问题描述
设B是一个n×n棋盘,n=2k,(k=1,2,3,…)。用分治法设计一个算法,使得:用若干个L型条块可以覆盖住B的除一个特殊方格外的所有方格。其中,一个L型条块可以覆盖3个方格。且任意两个L型条块不能重叠覆盖棋盘。
例如:如果n=2,则存在4个方格,其中,除一个方格外,其余3个方格可被一L型条块覆盖;当n=4时,则存在16个方格,其中,除一个方格外,其余15个方格被5个L型条块覆盖。
2. 具体要求
输入一个正整数n,表示棋盘的大小是n*n的。输出一个被L型条块覆盖的n*n棋盘。该棋盘除一个方格外,其余各方格都被L型条块覆盖住。为区别出各个方格是被哪个L型条块所覆盖,每个L型条块用不同的数字或颜色、标记表示。
3. 测试数据(仅作为参考)
输入:8
输出:A 2 3 3 7 7 8 8
2 2 1 3 7 6 6 8
4 1 1 5 9 9 6 10
4 4 5 5 0 9 10 10
12 12 13 0 0 17 18 18
12 11 13 13 17 17 16 18
14 11 11 15 19 16 16 20
14 14 15 15 19 19 20 20
4. 设计与实现的提示
对2k×2k的棋盘可以划分成若干块,每块棋盘是原棋盘的子棋盘或者可以转化成原棋盘的子棋盘。
注意:特殊方格的位置是任意的。而且,L型条块是可以旋转放置的。
为了区分出棋盘上的方格被不同的L型条块所覆盖,每个L型条块可以用不同的数字、颜色等来标记区分。
#include <stdio.h>
#include <malloc.h>
#include <math.h>
void shape(int *a, int n, int m, int type, int x, int y);
int num;
int main(){
int n;
int i, j;
int *a;
while(1){
num=0;
printf("输入行数,为2的k次方\n");
scanf("%d", &n);
a = (int *)malloc(sizeof(char *)*n*n);
*(a)=-1;
shape(a, n, n, 3, 0, 0);
for(i=0; i<n; i++){
for(j=0; j<n; j++){
printf("%3d ", *(a + i*n + j));
}
printf("\n");
}
printf("\n");
free(a);
}
}//type=0 左上角, type=1 右上角, type=2 左下角, type=3 右下角
void shape(int *a, int n, int m, int type, int x, int y){
if(m == 1){
return;
}
if(type == 0){
*(a + (y + m/2 - 1)*n + (x + m/2 - 1)) = num;
*(a + (y + m/2 - 1)*n + (x + m/2)) = num;
*(a + (y + m/2)*n + (x + m/2 - 1)) = num;
num++;
shape(a, n, m/2, 0, x, y);
shape(a, n, m/2, 1, x+m/2, y);
shape(a, n, m/2, 2, x, y+m/2);
shape(a, n, m/2, 0, x+m/2, y+m/2);
}else if(type == 1){
*(a + (y + m/2 - 1)*n + (x + m/2 - 1)) = num;
*(a + (y + m/2 - 1)*n + (x + m/2)) = num;
*(a + (y + m/2)*n + (x + m/2)) = num;
num++;
shape(a, n, m/2, 0, x, y);
shape(a, n, m/2, 1, x+m/2, y);
shape(a, n, m/2, 1, x, y+m/2);
shape(a, n, m/2, 3, x+m/2, y+m/2);
}else if(type == 2){
*(a + (y + m/2 - 1)*n + (x + m/2 - 1)) = num;
*(a + (y + m/2)*n + (x + m/2 - 1)) = num;
*(a + (y + m/2)*n + (x + m/2)) = num;
num++;
shape(a, n, m/2, 0, x, y);
shape(a, n, m/2, 2, x+m/2, y);
shape(a, n, m/2, 2, x, y+m/2);
shape(a, n, m/2, 3, x+m/2, y+m/2);
}else if(type == 3){
*(a + (y + m/2 - 1)*n + (x + m/2)) = num; //(m/2,m/2-1)
*(a + (y + m/2)*n + (x + m/2 -1)) = num; //(m/2-1,m/2)
*(a + (y + m/2)*n + (x + m/2)) = num; //(m/2,m/2)
num++;
shape(a, n, m/2, 3, x, y);
shape(a, n, m/2, 1, x+m/2, y);
shape(a, n, m/2, 2, x, y+m/2);
shape(a, n, m/2, 3, x+m/2, y+m/2);
}
}
运行结果: