http://acm.hdu.edu.cn/showproblem.php?pid=1542
Ah ~ ~ ~ ~ ~ ~ to finish this problem feeling IQ is hollowed out ....
1, firstly, because the horizontal ordinate is not necessarily an integer, it needs to be discretized according to the actual data;
2, because my scan is from bottom to top, so the horizontal axis is discretized;
3, from the bottom of the scan, when encountered a bottom edge will cover the number plus one, or minus one;
4, each time the enumeration of each edge, adding the height difference between the front and back two edges multiplied by the interval coverage length;
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace
Std
const int maxn=1009;
Double pos[maxn*2];//preserves the result of discretization of the struct line {double l,r,h;
The int f;//mark is the edge of the above (1) or the bottom edge ( -1)} seg[maxn<<1];
struct node {int l,r,cnt;
Double Len;
} ac[maxn<<3]; int CMP (line A,line b) {return a.h<b.h;//is sorted by height by segment} void build (int l,int r,int RT)//build maintains a closed interval {AC[RT].L
=l,ac[rt].r=r,ac[rt].len=ac[rt].cnt=0;
if (l==r) return;
int m=ac[rt].l+ac[rt].r>>1;
Build (l,m,rt<<1);
Build (m+1,r,rt<<1|1); } void Pushup (int rt)//Why add one, because build maintains a closed interval. When we update, we update that a left-closed-right-open interval {if (ac[rt].cnt) ac[rt].len=pos[ac[rt].r+1]-pos[ac[rt].l];//cnt nonzero is all overridden by the else if (ac[rt].l==a
C[RT].R) ac[rt].len=0;//is no longer a segment else ac[rt].len=ac[rt<<1].len+ac[rt<<1|1].len;//if the interval coverage is discontinuous, then the value from the sub-interval is found} int fin (double key,int low,int High)//find the discretized position {while (low<=high) {int mid=high+low>>1;
if (Pos[mid]==key) return mid;
else if (Pos[mid]<key) low=mid+1;
else high=mid-1;
} return-1;
} void Update (int l,int r,int Val,int rt) {if (L<=AC[RT].L&&R>=AC[RT].R) {ac[rt].cnt+=val;
Pushup (RT);
Return
} int m=ac[rt].l+ac[rt].r>>1;
if (m>=r) update (L,R,VAL,RT<<1);
else if (m<l) update (L,R,VAL,RT<<1|1);
else {update (l,r,val,rt<<1);
Update (L,R,VAL,RT<<1|1);
} pushup (RT);
} int main () {int ase=1;
int n;
while (scanf ("%d", &n) &&n) {double x1,x2,y1,y2;
int m=0;
for (int i=0; i<n; i++) {scanf ("%lf%lf%lf%lf", &x1,&y1,&x2,&y2); seg[m].l=x1,seg[m].r=x2,seg[m].h=y1,seg[m].f=1;//encounters the following edge and adds a seg[m+1].l=x1,seg[m+1].r=x2,seg[m+1].h=y2,seg[m+1]. f=-1;//meet the upper edge, minus one pos[m]=x1,pos[m+.1]=x2;
m+=2;
} sort (seg,seg+m,cmp);
Sort (pos,pos+m);
int cnt=1;
for (int i=1; i<m; i++)//discretization after de-weight if (pos[i]!=pos[i-1]) pos[cnt++]=pos[i];
Build (0,cnt-1,1);
Double ans=0;
for (int i=0; i<m; i++) {int Left=fin (seg[i].l,0,cnt-1);
int Right=fin (seg[i].r,0,cnt-1) -1;//to be reduced by an update (left,right,seg[i].f,1);
ans+= (seg[i+1].h-seg[i].h) *ac[1].len;
} printf ("Test case #%d\n", ase++);
printf ("Total explored area:%.2f\n\n", ans);
} return 0;
}