洛谷 P1228 地毯填补问题(分治)
传送门
解题思路
乍一看像是构造题。
我们从简单开始想。
当有一个2*2的方格,很显然可以直接铺上。
于是我们发现,当一个矩形的1/4已经铺好后,剩下的也可以铺。
就像下图一样:(图片来源:洛谷网校)
突破点:在已经铺好的1/4的矩形正对着的位置铺一个。
就像这样:
所以可以分治处理,判断已经填好的矩形在哪个位置。
AC代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
int x,y,k;
void divide(int lx,int ly,int rx,int ry,int x,int y){
if(lx==rx&&ly==ry){
return;
}
int midx=(lx+rx)/2,midy=(ry+ly)/2;
if(x>=lx&&x<=midx&&y>=ly&&y<=midy){
cout<<midx+1<<" "<<midy+1<<" "<<1<<endl;
divide(lx,ly,midx,midy,x,y);
divide(lx,midy+1,midx,ry,midx,midy+1);
divide(midx+1,ly,rx,midy,midx+1,midy);
divide(midx+1,midy+1,rx,ry,midx+1,midy+1);
return;
}
if(x>midx&&x<=rx&&y>=ly&&y<=midy){
cout<<midx<<" "<<midy+1<<" "<<3<<endl;
divide(lx,ly,midx,midy,midx,midy);
divide(lx,midy+1,midx,ry,midx,midy+1);
divide(midx+1,ly,rx,midy,x,y);
divide(midx+1,midy+1,rx,ry,midx+1,midy+1);
return;
}
if(x>=lx&&x<=midx&&y>midy&&y<=ry){
cout<<midx+1<<" "<<midy<<" "<<2<<endl;
divide(lx,ly,midx,midy,midx,midy);
divide(lx,midy+1,midx,ry,x,y);
divide(midx+1,ly,rx,midy,midx+1,midy);
divide(midx+1,midy+1,rx,ry,midx+1,midy+1);
return;
}
if(x>midx&&x<=rx&&y>midy&&y<=ry){
cout<<midx<<" "<<midy<<" "<<4<<endl;
divide(lx,ly,midx,midy,midx,midy);
divide(lx,midy+1,midx,ry,midx,midy+1);
divide(midx+1,ly,rx,midy,midx+1,midy);
divide(midx+1,midy+1,rx,ry,x,y);
return;
}
}
int main(){
ios::sync_with_stdio(false);
cin>>k>>x>>y;
divide(1,1,1<<k,1<<k,x,y);
return 0;
}