一开始为了节省时间设了-1.
遇到0就不往下搜,结果没想清楚,各种bug.
基本思路就是离散化x的小数(详细点的说明在这里).
用平行x轴的扫描线扫描整个区域.
每次扫描把已经染色的长度算(endis[r]-endis[l])出来,乘以这次于上一次y的差就是本次的差.
还有就是区间的连续,也就是为什么是(endis[r]-endis[l]),这里用的是叶节点为[1,2][[2,3]...这种划分.就避免了需要判断是否区间连续.
/**********************
hash x
scan line on y
**********************/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#define lson num<<1
#define rson num<<1|1
#define gl l,(l+r)>>1,lson
#define gr (l+r)>>1,r,rson
using namespace std;
const int maxn = 100005;
struct ord ///save order
{
double y,x[2];
int flag;
}o[210];
bool ord_cmp (ord a,ord b) {return a.y<b.y;}
int st[500<<3];
void push_down(int num) ///push_down without hesitates
{
st[lson]+=st[num];
st[rson]+=st[num];
st[num]=0;
}
void push_up(int num) ///push_up without hesitates
{
int v=min(st[lson],st[rson]);
st[num]+=v;
st[lson]-=v;
st[rson]-=v;
}
void updata(int a,int b,int v,int l,int r,int num)
{
if(a<=l&&r<=b)
{
st[num]+=v;
push_up(num);
return;
}
if(l+1==r)
return;
push_down(num);
updata(a,b,v,gl);
updata(a,b,v,gr);
push_up(num);
}
map<double,int> dis; ///discrete
map<int,double>endis; ///continuous
set<double>buf; ///buffer for dis
double calc(int l,int r,int num)
{
if(st[num])
return endis[r]-endis[l];
if(l+1==r)
return 0;
push_down(num);
return calc(gl)+calc(gr);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("poj1151.in","r",stdin);
#endif // ONLINE_JUDGE
int n,cas=1;
while(~scanf("%d",&n)&&n)
{
buf.clear();
dis.clear();
endis.clear();
for(int i=0;i<n;i++)
{
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
buf.insert(a);
buf.insert(c);
o[i*2+1].x[0]=o[i*2].x[0]=min(a,c);
o[i*2+1].x[1]=o[i*2].x[1]=max(a,c);
o[i*2].y=min(b,d);
o[i*2+1].y=max(b,d);
o[i*2].flag=1;
o[i*2+1].flag=-1;
}
sort(o,o+n*2,ord_cmp);
int cnt=1;
for(set<double>::iterator i=buf.begin(),end=buf.end();i!=end;i++,cnt++)
{
pair<double,int>tmp1(*i,cnt);
pair<int,double>tmp2(cnt,*i);
dis.insert(tmp1);
endis.insert(tmp2);
}
n*=2;
int m=buf.size();
double ans=0,last=o[0].y;
for(int i=0;i<n;i++)
{
int a=dis[o[i].x[0]],b=dis[o[i].x[1]];
if(last!=o[i].y)
{
ans+=calc(1,m,1)*(o[i].y-o[i-1].y);
last = o[i].y;
}
updata(a,b,o[i].flag,1,m,1);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",cas++,ans);
}
return 0;
}