2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
7.63 0.00
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1255
题意:就是求覆盖两次以上的图形的面积
分析:只要在求矩形面积并的基础上加上一个统计覆盖超过两次的长度,如果要求覆盖三次,那就再开一个,貌似有点土,不过好一点的方法没想到。。。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define ls rt<<1 #define rs rt<<1|1 #define lson l,m,ls #define rson m,r,rs using namespace std; const int mm=2222; const int mn=mm<<2; struct seg { double x,y1,y2; int val; }g[mm]; double len[mn],ret[mn],y[mm],L,R; int t[mn],val; void build(int n) { while(n--)ret[n]=len[n]=t[n]=0; } void updata(int l,int r,int rt) { if(L<=y[l]&&R>=y[r])t[rt]+=val; else { int m=(l+r)>>1; if(L<y[m])updata(lson); if(R>y[m])updata(rson); } if(t[rt]>1)ret[rt]=len[rt]=y[r]-y[l]; else if(t[rt]>0)len[rt]=y[r]-y[l],ret[rt]=len[ls]+len[rs]; else if(l>=r)ret[rt]=len[rt]=0; else len[rt]=len[ls]+len[rs],ret[rt]=ret[ls]+ret[rs]; } bool cmp(seg a,seg b) { return a.x<b.x; } int main() { int i,m,n,cs; double ans; scanf("%d",&cs); while(cs--) { scanf("%d",&n); for(i=0;i<n;++i) { scanf("%lf%lf%lf%lf",&g[i].x,&y[i],&g[i+n].x,&y[i+n]); g[i].y1=y[i],g[i].y2=y[i+n],g[i].val=1; g[i+n].y1=y[i],g[i+n].y2=y[i+n],g[i+n].val=-1; } sort(y,y+n+n); sort(g,g+n+n,cmp); for(m=i=0;i<n+n;++i) if(y[m]<y[i])y[++m]=y[i]; build(m<<2); for(ans=i=0;i<n+n;++i) { L=g[i].y1,R=g[i].y2,val=g[i].val; updata(0,m,1); if(g[i].x<g[i+1].x)ans+=(g[i+1].x-g[i].x)*ret[1]; } printf("%.2lf\n",ans); } return 0; }