受此链接很大启发才明白扫描线:
http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
我的代码如下:
#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<double,double> ll;
vector<double>x;
int n;
struct node
{
double l,r,y;
int flag;
}seg[201];
struct node1
{
int l,r,m;
double y;
int flag;
}tree[801];
bool cmp(double a,double b)
{
return a<b;
}
bool cmp1(node a,node b)
{
return a.y<b.y;
}
void create(int l,int r,int k)
{
tree[k].l=l;
tree[k].r=r;
tree[k].m=(l+r)>>1;
tree[k].flag=0;
if(l+1==r)
return;
create(l,tree[k].m,k<<1);
create(tree[k].m,r,k<<1|1);
}
void join(int l,int r,int flag,int k)
{
if(tree[k].l==l&&tree[k].r==r)
{
tree[k].flag+=flag;
return;
}
if(r<=tree[k].m)
join(l,r,flag,k<<1);
else if(l>=tree[k].m)
join(l,r,flag,k<<1|1);
else
{
join(l,tree[k].m,flag,k<<1);
join(tree[k].m,r,flag,k<<1|1);
}
}
double find(int k)
{
if(tree[k].flag>0)
return x[tree[k].r]-x[tree[k].l];
if(tree[k].l+1==tree[k].r)
return 0;
return find(k<<1)+find(k<<1|1);
}
void in()
{
ll t1,t2;
int i=0;
x.clear();
while(n--)
{
cin>>t1.first>>t1.second>>t2.first>>t2.second;
seg[i].l=t1.first;
seg[i].r=t2.first;
seg[i].y=t1.second;
seg[i].flag=1;
x.push_back(t1.first);
i++;
seg[i].l=t1.first;
seg[i].r=t2.first;
seg[i].y=t2.second;
seg[i].flag=-1;
x.push_back(t2.first);
i++;
}
n=i;
sort(x.begin(),x.end(),cmp);
x.erase(unique(x.begin(),x.end()),x.end());
create(0,n-1,1);
}
double work()
{
double ans=0,t1;
int i,l,r;
sort(seg,seg+n,cmp1);
n--;
for(i=0;i<n;i++)
{
l=lower_bound(x.begin(),x.end(),seg[i].l)-x.begin();
r=lower_bound(x.begin(),x.end(),seg[i].r)-x.begin();
join(l,r,seg[i].flag,1);
t1=find(1);
ans+=find(1)*(seg[i+1].y-seg[i].y);
}
return ans;
}
int main()
{
int jishu=0;
while(cin>>n&&n!=0)
{
in();
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++jishu,work());
}
}