棋盘覆盖问题

来源:互联网 发布:工业产品网络推广 编辑:程序博客网 时间:2024/06/10 17:05
       有一个有2^k×2^k个方格的棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图(1)所示为L型牌的四种旋转方式。
     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个:
                                          

图(1)

输入格式:

第一行含有三个数据:分别为n(<=50 <=0 保证是4的倍数):棋盘边长,x(<=n >=1):特殊方格横坐标,y(<=n >=1):特殊方格纵坐标。


输入样例:

8 5 6


输出样例:

  4  4  5  5  9  9 10 10
  4  2  2  5  9  7  7 10
  6  2  0  3  8  8  7 11
  6  6  3  3  1  8 11 11
 14 14 13  1  1 18 19 19
 14 12 13 13 18 18 17 19
 15 12 12 16 20 17 17 21
 15 15 16 16 20 20 21 21




本题解题思路:

图为样例输入

先将棋盘分割成四个子棋盘,再将没有特殊方格的子棋盘的靠近分割点的三格覆盖骨牌。
       将子棋盘再分割成四个更小的子棋盘,并按照之前的方法,将黄色格子当做特殊格子,实现分治,将没有特殊方格的子棋盘的靠近中心分割点的三格覆盖骨牌。
子棋盘为2×2时填充剩下的格子便完成了。

代码如下:
#include<cstdio>using namespace std;int x,y,n,i,j,t=0; //x:特殊格子横坐标 y:特殊格子纵坐标 n:棋盘边长 i,j:循环变量 t:当前骨牌编号 int map[51][51]; //本程序使用递归实现分治. void CB(int x,int y,int m,int n,int s)//x:棋盘左上角横坐标 y:棋盘左上角纵坐标 m:特殊格子横坐标 n:特殊格子纵坐标 s:棋盘边长 {int sa,temp;//sa:子棋盘边长  temp:交换临时变量 if(s==2)//递归边界:子棋盘边长=2 {temp=map[m][n];//先将四个格子全部覆盖,再将原来的特殊格子重新填充 map[x][y]=t+1; map[x][y+1]=t+1;map[x+1][y]=t+1;map[x+1][y+1]=t+1;map[m][n]=temp;t++;return;} t++; sa=s/2;if(m<x+sa && n<y+sa) //特殊格子在左上角 {map[x+sa-1][y+sa]=t;//摆放骨牌 map[x+sa][y+sa-1]=t;map[x+sa][y+sa]=t;CB(x,y,m,n,sa);//递归调用子棋盘 CB(x,y+sa,x+sa-1,y+sa,sa);CB(x+sa,y,x+sa,y+sa-1,sa);CB(x+sa,y+sa,x+sa,y+sa,sa);}if(m<x+sa && n>=y+sa) //特殊格子在右上角{map[x+sa-1][y+sa-1]=t;//摆放骨牌map[x+sa][y+sa-1]=t;map[x+sa][y+sa]=t;CB(x,y+sa,m,n,sa);//递归调用子棋盘 CB(x,y,x+sa-1,y+sa-1,sa);CB(x+sa,y,x+sa,y+sa-1,sa);CB(x+sa,y+sa,x+sa,y+sa,sa);}if(m>=x+sa && n<y+sa) //特殊格子在左下角{map[x+sa-1][y+sa-1]=t;//摆放骨牌map[x+sa-1][y+sa]=t;map[x+sa][y+sa]=t;CB(x+sa,y,m,n,sa);//递归调用子棋盘 CB(x,y,x+sa-1,y+sa-1,sa);CB(x,y+sa,x+sa-1,y+sa,sa);CB(x+sa,y+sa,x+sa,y+sa,sa);}if(m>=x+sa && n>=y+sa) //特殊格子在右下角{map[x+sa-1][y+sa-1]=t;//摆放骨牌map[x+sa-1][y+sa]=t;map[x+sa][y+sa-1]=t;CB(x+sa,y+sa,m,n,sa);//递归调用子棋盘 CB(x,y,x+sa-1,y+sa-1,sa);CB(x,y+sa,x+sa-1,y+sa,sa);CB(x+sa,y,x+sa,y+sa-1,sa);}}int main(){scanf("%d%d%d",&n,&x,&y);//n:棋盘边长 x:特殊格子横坐标 y:特殊格子纵坐标CB(1,1,x,y,n);//调用递归 for(i=1;i<=n;i++)//循环输出结果 {for(j=1;j<=n;j++) printf("%3d",map[i][j]);printf("\n");}return 0;}



1 0
原创粉丝点击