扩地:有N块不重叠的矩形地,由左下角(A,B)和右上角(C,D)决定。如果两块地的边或角相交,则两块地都无法扩大。求多少地可以扩大?
思路:其实就是对x轴扫描,对y轴扫描。详见代码上的注释
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int p,mi,ma,id;
node(){}
node(int p,int mi,int ma,int id):p(p),mi(mi),ma(ma),id(id){}
/*bool operator < (const node& rhs) const {
return p < rhs.p || (p == rhs.p && mi < rhs.mi) ||
(p == rhs.p && mi == rhs.mi && ma < rhs.ma);
}*/
};
bool fg[25004];
vector<node> vx;
vector<node> vy;
bool cmp(node a,node b)
{
if (a.p==b.p)
{
if(a.mi==b.mi)
return a.ma<b.ma;
else
return a.mi<b.mi;
}
else
return a.p<b.p;
}
int main()
{
//freopen("t.txt","r",stdin);
int x1,x2,y1,y2,n,temp;
while(scanf("%d",&n)!=EOF)
{
vx.clear();
vy.clear();
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
vx.push_back(node(y1,x1,x2,i));
vx.push_back(node(y2,x1,x2,i));
vy.push_back(node(x1,y1,y2,i));
vy.push_back(node(x2,y1,y2,i));
}
sort(vx.begin(),vx.end(),cmp);
sort(vy.begin(),vy.end(),cmp);
memset(fg,true,sizeof(fg));
temp=vx[0].ma;
for(int i=1;i<vx.size();i++)
{
if(vx[i-1].p==vx[i].p){
if(temp>=vx[i].mi)
fg[vx[i].id]=fg[vx[i-1].id]=false;
//这种方法类似于竹取法,显示讨论在同一行上的所有x,因为ximin 是从小到大排列的,所以每次搞得时候temp= max(temp,vx[i].ma),
//这样下次的xi+1min>ximin,若是xi+1min仍然无法大于temp,说明一定被前面的区间包括了。
}else{
temp=vx[i].ma;
}
temp=max(temp,vx[i].ma);
}
temp=vy[0].ma;
for(int i=1;i<vy.size();i++)
{
if(vy[i-1].p==vy[i].p){
if(temp>=vy[i].mi)
fg[vy[i].id]=fg[vy[i-1].id]=false;
}else{
temp=vy[i].ma;
}
temp=max(temp,vy[i].ma);
}
int ans=0;
for(int i=0;i<n;i++)
if(fg[i]) ans++;
printf("%d\n",ans);
}
return 0;
}