标签:vector 图形 while xpl std include exp node explore
题目含义
每一行给出两个点,代表一个矩形的左下角端点和右上角端点
要你求出这些矩形覆盖坐标轴的整个面积
题目分析
用平行x轴的扫描线扫描整个图形,得到很多长宽不同的矩形,求出面积再相加
将每个矩形的面积记作 len(x)*len(y)
每个len(x)我们通过加减每个点的x左右坐标,通过线段树求sum[1]得到
每个len(y)我们通过这个点与下一个点的y坐标的差得到
所以我们要把所有点按y轴大小排序,并且记录每个点的左右x轴坐标
注意:这里用的线段树sum【l,r】不是指区间【l,r】的和,而是指X.l和X.r的差
题目代码
#include<stdio.h> #include<iostream> #include<vector> #include<string.h> #include<algorithm> using namespace std; const int maxn=1e5+7; typedef long long LL; vector<double>v; int n; double x1,y1,x2,y2; double len[maxn<<2]; int cov[maxn<<2]; struct node{ double y,x1,x2; int k; }rem[maxn]; int getid(double x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } bool cmp(node a,node b){ return a.y<b.y; } void pushup(int l,int r,int rt){ if(cov[rt]>0)len[rt]=v[r]-v[l-1]; else if(l==r)len[rt]=0; else len[rt]=len[rt<<1]+len[rt<<1|1]; } void updata(int l,int r,int rt,int ll,int rr,int k){ if(ll<=l&&r<=rr){ cov[rt]+=k; pushup(l,r,rt); return; } int mid=(l+r)>>1; if(ll<=mid)updata(l,mid,rt<<1,ll,rr,k); if(rr>mid)updata(mid+1,r,rt<<1|1,ll,rr,k); pushup(l,r,rt); } int main(){ int ce=0; while(scanf("%d",&n)&&n){ memset(len,0,sizeof(len)); memset(cov,0,sizeof(cov)); v.clear(); int cnt=0; for(int i=0;i<n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); v.push_back(x1); v.push_back(x2); rem[++cnt].x1=x1,rem[cnt].x2=x2,rem[cnt].y=y1,rem[cnt].k=1; rem[++cnt].x1=x1,rem[cnt].x2=x2,rem[cnt].y=y2,rem[cnt].k=-1; } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); sort(rem+1,rem+1+cnt,cmp); double ans=0; for(int i=1;i<cnt;i++){ updata(1,cnt,1,getid(rem[i].x1),getid(rem[i].x2)-1,rem[i].k); ans+=len[1]*(rem[i+1].y-rem[i].y); } printf("Test case #%d\nTotal explored area: %.2f\n\n",++ce,ans); } return 0; }
标签:vector 图形 while xpl std include exp node explore
原文地址:https://www.cnblogs.com/helman/p/11226607.html