洛谷P1228 地毯填补问题
题意:
用如图所示的四种方块填充一个边长为
2
k
2^k
2k的正方形,其中正方形坐标为(x,y)的点不能被填充,需要空出。输出任意一种方案。(每个填充的方块输出其拐角坐标)
思路:
考虑由简到繁,对于k=1时,假设这个特殊点在(2,2),那么很明显正确的填法是这样的:
k=2时
k=3时
观察图片,我们可以发现,在大正方形最中间加一个(缺口朝向当前大正方形的空缺格子)的填充块,使得把大正方形分成四个等边长的小正方形后,每个小正方形中都有一个空缺格子。递归这个操作,当边长为1时return。
时间复杂度 O ( 4 n ) O(4^n) O(4n)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll inf=2e10;
const int maxn = 2e6+5;
const ll mod=1e9+7;
int n,s,t;
void dfs(int x,int y,int a,int b,int l){
if(l==1)return;
if(x>a+l/2-1&&y<=b+l/2-1){
printf("%d %d 3\n",a+l/2-1,b+l/2);
dfs(x,y,a+l/2,b,l/2);
dfs(a+l/2-1,b+l/2-1,a,b,l/2);
dfs(a+l/2-1,b+l/2,a,b+l/2,l/2);
dfs(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
}
else if(x<=a+l/2-1&&y<=b+l/2-1){
printf("%d %d 1\n",a+l/2,b+l/2);
dfs(x,y,a,b,l/2);
dfs(a+l/2-1,b+l/2,a,b+l/2,l/2);
dfs(a+l/2,b+l/2-1,a+l/2,b,l/2);
dfs(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
}
else if(x<=a+l/2-1&&y>b+l/2-1){
printf("%d %d 2\n",a+l/2,b+l/2-1);
dfs(x,y,a,b+l/2,l/2);
dfs(a+l/2-1,b+l/2-1,a,b,l/2);
dfs(a+l/2,b+l/2-1,a+l/2,b,l/2);
dfs(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
}
else {
printf("%d %d 4\n",a+l/2-1,b+l/2-1);
dfs(x,y,a+l/2,b+l/2,l/2);
dfs(a+l/2-1,b+l/2-1,a,b,l/2);
dfs(a+l/2-1,b+l/2,a,b+l/2,l/2);
dfs(a+l/2,b+l/2-1,a+l/2,b,l/2);
}
}
int main(){
scanf("%d%d%d",&n,&s,&t);
dfs(s,t,1,1,pow(2,n));
}