算法实验1:棋盘覆盖
Time Limit: 1 Sec Memory Limit: 64 MB Submit: 2798 Solved: 702 [Submit][Status][Discuss]Description
在一个2k x 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
口 口 口 口 口 口
口 口 , 口 口 , 口 , 口
Input
k,dr,dc。k定义如前,dr,dc分别表示特殊方格所在的行号和列号 1= < k < =6
Output
按照左上,右上,左下,右下的顺序用分治法求解。特殊方格标0,其他位置按上述顺序依次标记。
Sample Input
2 1 1
Sample Output
2 2 3 3 2 0 1 3 4 1 1 5 4 4 5 5
HINT
了解递归执行的过程,理解分治法。
Source
思路:分治--把大的分成类似的小的来解,把正方形中间的看做特殊点(先分成4个小的
正方形,找出没有特殊点的那个正方形,把另外3个属于大正方形的中间那个点当做特殊点),
3个特殊点连成一个上面的L骨牌,这样,每个小正方形都有一个特殊点,当2x2的时候,无论
特殊点在哪都可以与L骨牌合成一个正方形,再然后为1x1,结束;
#include <stdio.h> int Ts[100][100]; int tile=1; void ches(int,int,int,int,int); void ches(int h1,int l1,int x,int y,int size) { int t,s; if(size==1) return ; t=tile++; s=size/2; if(x<s+h1&&y<s+l1) ches(h1,l1,x,y,s); else { Ts[s+h1-1][s+l1-1]=t; ches(h1,l1,s+h1-1,s+l1-1,s); } if(x<s+h1&&y>=l1+s) ches(h1,l1+s,x,y,s); else { Ts[h1+s-1][l1+s]=t; ches(h1,l1+s,h1+s-1,l1+s,s); } if(x>=h1+s&&y<l1+s) ches(h1+s,l1,x,y,s); else { Ts[h1+s][l1+s-1]=t; ches(h1+s,l1,h1+s,l1+s-1,s); } if(x>=h1+s&&y>=l1+s) ches(h1+s,l1+s,x,y,s); else { Ts[h1+s][l1+s]=t; ches(h1+s,l1+s,h1+s,l1+s,s); } } int main() { int n,x,y,size=1,i,j; scanf("%d",&n); scanf("%d%d",&x,&y); while(n--) size *= 2; ches(0,0,x,y,size); for(i=0;i<size;i++) { for(j=0;j<size;j++) printf("%d ",Ts[i][j]); printf(" "); } return 0; }