思路:纯纯扫描线求面积模板题,求点赞qaq。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1e3+20;
double xx[maxn<<1];
struct Edge
{
double l,r,h;
int inout;
Edge() {}
Edge(double x1,double x2, double y, int inout):l(x1),r(x2),h(y),inout(inout) {}
} e[maxn<<1];
bool cmp(Edge a, Edge b)
{
return a.h<b.h;
}
struct Tree
{
int l, r;
double len;
int s;
int mid()
{
return (l+r)>>1;
}
}tr[maxn<<2];
void pushup(int now)
{
if(tr[now].s)
tr[now].len = xx[tr[now].r+1]-xx[tr[now].l];
else if(tr[now].l == tr[now].r)
tr[now].len = 0;//这里不能写return
else
tr[now].len = tr[now<<1].len + tr[now<<1|1].len;
}
void build(int now, int l, int r)
{
tr[now].l = l, tr[now].r = r;
tr[now].s = 0, tr[now].len = 0;
int mid = tr[now].mid();
if(tr[now].l == tr[now].r)return;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
}
void update(int now,int l, int r,int val)
{
if(tr[now].l>=l && tr[now].r <=r)
{
tr[now].s +=val;
pushup(now);
return;
}
int mid = tr[now].mid();
if(mid>=r)
{
update(now<<1,l,r,val);
}
else if(mid<l)
update(now<<1|1,l,r,val);
else
{
update(now<<1, l,mid,val);
update(now<<1|1, mid+1, r, val);
}
pushup(now);
}
int main()
{
double x1, x2,y1,y2;
int flag= 1;
while(scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2)!=EOF)
{
int cnt = 0;
if(flag == 0&&x1 == -1 && x2 == -1 && y1 == -1 && y2 == -1)
break;
else
flag= 1;
xx[++cnt] = x1;
e[cnt] = Edge(x1, x2,y1,1);
xx[++cnt] = x2;
e[cnt] = Edge(x1,x2,y2,-1);
while(scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2)!=EOF)
{
if(x1 == -1 && x2 == -1 && y1 == -1 && y2 == -1)
{
flag = 0;
break;
}
xx[++cnt] = x1;
e[cnt] = Edge(x1, x2,y1,1);
xx[++cnt] = x2;
e[cnt] = Edge(x1,x2,y2,-1);
}
sort(xx+1,xx+1+cnt);
sort(e+1,e+1+cnt,cmp);
int len = unique(xx+1,xx+1+cnt)-(xx+1);
build(1,1,len);
double area = 0;
for(int i = 1;i<cnt;i++)
{
int l = lower_bound(xx+1,xx+1+len,e[i].l)-xx;
int r = lower_bound(xx+1, xx+1+len,e[i].r)-xx-1;
update(1,l,r,e[i].inout);
area+= tr[1].len *(e[i+1].h-e[i].h);
}
printf("%.0f\n",area);
}
return 0;
}