您的位置:首页 > 其它

棋盘覆盖问题的算法实现

2013-10-08 21:59 369 查看
在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。



 实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。以上原理如图1所示。



            图1

 将棋盘保存在一个二维数组中。骨牌号从2开始,特殊方格为1,如果是一个4 * 4的棋盘,特殊方格为(2,2),那么程序的输出为

3   3   4   4   

3   2   2   4   

5   2   1   6   

5   5   6   6

代码实现如下:

#include<stdio.h>
#define MAX 100
int Board[MAX][MAX]; // 骨盘号码记录
int number = 1;  // L型骨牌号

void ChessBoard(int tr , int tc , int x , int y ,int size) {
if(size == 1) {
return;
}
int t = ++number;  // 骨盘号自增
int s = size / 2;  // 分割棋盘
// 覆盖四分之一左上角子棋盘
if(x < tr + s && y < tc +s) { // 如果特殊方格在此子棋盘中
ChessBoard(tr , tc , x , y , s);
} else {                      // 如果特殊方格不在此子棋盘中
Board[tr+s-1][tc+s-1] = t; // 覆盖右下角
ChessBoard(tr , tc , tr+s-1 , tc+s-1 , s); // 覆盖其余的
}
// 覆盖四分之一右上角子棋盘
if(x < tr + s && y >= tc + s) {
ChessBoard(tr , tc+s , x , y , s);
} else {
Board[tr + s - 1][tc + s] = t;
ChessBoard(tr , tc+s , tr+s-1 , tc+s , s);
}
// 覆盖四分之一左下角子棋盘
if(x >= tr+s && y < tc+s) {
ChessBoard(tr+s , tc , x , y , s);
} else {
Board[tr + s][tc + s - 1] = t;
ChessBoard(tr+s , tc , tr + s , tc + s - 1 , s);
}
// 覆盖四分之一右下角子棋盘
if(x >= tr+s && y >= tc+s) {
ChessBoard(tr+s , tc+s , x , y , s);
} else {
Board[tr + s][tc + s] = t;
ChessBoard(tr+s , tc+s , tr + s , tc + s , s);
}

}

int main() {
int size , x , y;
int i , j;
printf("请先输入size的尺寸:\n");
// 方格左上角坐标从(1,1)开始
scanf("%d",&size);
printf("输入开始覆盖的点坐标x,y\n");
scanf("%d %d" , &x , &y);
Board[x][y] = number;
ChessBoard(1,1,x,y,size);
printf("结果为:\n");
for(i =1;i<=size;i++) {
for(j=1;j<=size;j++) {
printf("%2d " , Board[i][j]);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 分治法