题意:
给你一些小矩形,这些小矩形每个都存在于某一个大矩形内部,两个大矩形可以合并当且仅当他们相邻且合并后也是一个矩形,任意两个大矩形不可相交,问你是否存在一种大矩形摆放方案使得这些大矩形最终可以合并成一个大矩形。
题解:
那么这道题就变成了能否将一个矩形割成多个大矩形且每个大矩形内都有一个给你的小矩形。
如果存在分割方案的话,那么对于当前的矩形,一定有一条横着或者竖着的线将其分为两块。那么我们只需要分治的去做每一个块即可,时间复杂度
O
(
n
2
l
o
g
n
)
O(n^2logn)
O(n2logn);
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
struct node
{
int l,r,u,d;
void in(){scanf("%d%d%d%d",&l,&d,&r,&u);}
}rec[N];
bool cmp1(node a,node b){return a.l<b.l;}
bool cmp2(node a,node b){return a.d<b.d;}
vector<node>vec,t;
queue<vector<node> >Q;
bool solve()
{
if(vec.size()==1)
return 1;
sort(vec.begin(),vec.end(),cmp1);
int mx=vec[0].r;
for(int i=1;i<vec.size();i++)
{
if(vec[i].l>=mx)
{
t.clear();
for(int j=0;j<i;j++)
t.push_back(vec[j]);
Q.push(t);
t.clear();
for(int j=i;j<vec.size();j++)
t.push_back(vec[j]);
Q.push(t);
return 1;
}
else
mx=max(mx,vec[i].r);
}
sort(vec.begin(),vec.end(),cmp2);
mx=vec[0].u;
for(int i=1;i<vec.size();i++)
{
if(vec[i].d>=mx)
{
t.clear();
for(int j=0;j<i;j++)
t.push_back(vec[j]);
Q.push(t);
t.clear();
for(int j=i;j<vec.size();j++)
t.push_back(vec[j]);
Q.push(t);
return 1;
}
else
mx=max(mx,vec[i].u);
}
return 0;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)rec[i].in(),vec.push_back(rec[i]);
Q.push(vec);
while(!Q.empty())
{
vec=Q.front();
Q.pop();
if(!solve())
return 0*printf("NO\n");
}
printf("YES\n");
return 0;
}