hdu1542(矩形面积并)
Posted shutdown113
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1542(矩形面积并)相关的知识,希望对你有一定的参考价值。
Atlantis
题意:
给你n个矩形,求这n个矩形组成的图形的面积。
分析:
扫描线的模板题,具体解释看代码注释吧。
学习资料:大佬博客(扫描线的具体步骤实现过程)
代码:
#include <map> #include <queue> #include <vector> #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=1e5+100; int n,Case=1; //延迟标记数组 int cnt[maxn<<2]; //x:垂直于x轴的线段的x坐标 //sum[rt]:rt所代表的区间内线段之间的相差距离 double x[maxn<<2],sum[maxn<<2]; struct Seg{ int s; double l,r,h; Seg() {} Seg(double l,double r,double h,int s):l(l),r(r),h(h),s(s) {} bool operator < (const Seg& rhs)const { return h<rhs.h; } }; Seg seg[maxn]; int binarySearch(double x,double* a,int n) { int l=0,r=n-1; while(l<=r) { int mid=(l+r)>>1; if(a[mid]==x) return mid; else if(a[mid]<x) l=mid+1; else if(a[mid]>x) r=mid-1; } return -1; } void PushUp(int rt,int l,int r) { //区间转换为具体线段 if(cnt[rt]) sum[rt]=x[r+1]-x[l]; //如果是叶子节点 else if(l==r) sum[rt]=0; else sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R){ cnt[rt]+=c; PushUp(rt,l,r); return; } int m=(l+r)>>1; if(L<=m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); PushUp(rt,l,r); } int main() { // freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n) { int m=0; for(int i=1;i<=n;i++){ double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); x[m]=x1; seg[m++]=Seg(x1,x2,y1,1); x[m]=x2; seg[m++]=Seg(x1,x2,y2,-1); } sort(x,x+m); sort(seg,seg+m); //去重 int k=1; for(int i=1;i<m;i++){ if(x[i]!=x[i-1]){ x[k++]=x[i]; } } cls(cnt); cls(sum); double ans=0; for(int i=0;i<m-1;i++){ //线段树处理的是区间,从第l条线段到第r条线段对应r-l个区间,所以r需要-1 int l=binarySearch(seg[i].l,x,k); int r=binarySearch(seg[i].r,x,k)-1; if(l<=r) update(l,r,seg[i].s,0,k-1,1); //两条线段之间的距离乘以这有效线段的长度 ans+=sum[1]*(seg[i+1].h-seg[i].h); } printf("Test case #%d ",Case++); printf("Total explored area: %.2lf ",ans); } return 0; }
以上是关于hdu1542(矩形面积并)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1542Atlantis 矩形面积并(线段树,扫描法)