洛谷 P1228 地毯填补问题(分治)

传送门


解题思路

乍一看像是构造题。
我们从简单开始想。
当有一个2*2的方格,很显然可以直接铺上。
于是我们发现,当一个矩形的1/4已经铺好后,剩下的也可以铺。
就像下图一样:(图片来源:洛谷网校)
image
突破点:在已经铺好的1/4的矩形正对着的位置铺一个。
就像这样:
image
所以可以分治处理,判断已经填好的矩形在哪个位置。

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;
}
posted @ 2021-09-22 09:59  尹昱钦  阅读(57)  评论(0编辑  收藏  举报