poj1151 Atlantis
252K 16MS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct point
{
double x;
double y;
};
struct map
{
point up;
point down;
}m[1000];
struct node
{
int L;
int R;
node *left;
node *right;
double len;//区间的长度
int count;//被覆盖的层数
}tree[1000];
int nodecount;
bool cmp(double a,double b)
{
return a<b;
}
void buildtree(node *p,int L,int R)
{
p->L=L;
p->R=R;
p->len=0;
p->count=0;
if(L!=R)
{
nodecount++;
p->left=tree+nodecount;
nodecount++;
p->right=tree+nodecount;
buildtree(p->left,L,(L+R)/2);
buildtree(p->right,(L+R)/2+1,R);
}
}
double s[1000];//第i个区间上端距y[0]的距离
struct li
{
double x;
double y1;//上面
double y2;//下面
bool left;
}line[5000];//一共n*2条直线
int k;
int nline;
double y[1000];
bool cnp(li a,li b)
{
return a.x<b.x;
}
double cal(int L,int R)//L号区间与R号区间距离
{
return y[R]-y[L-1];
}
int binsearch(double x)
{
int L=0;
int R=k-1;
int mid=(L+R)/2;
while(y[mid]!=x)
{
if(x<y[mid])
{
R=mid-1;
mid=(L+R)/2;
}
else
{
L=mid+1;
mid=(L+R)/2;
}
}
return mid+1;
}
void insert(node *p,int L,int R)
{
if((p->L)==L&&(p->R)==R)
{
p->count++;
p->len=cal(L,R);
return;
}
int mid=(p->L+p->R)/2;
if(R<=mid)
{
insert(p->left,L,R);
}
else if(L>=mid+1)
{
insert(p->right,L,R);
}
else
{
insert(p->left,L,mid);
insert(p->right,mid+1,R);
}
if(p->count==0)
{
p->len=p->left->len+p->right->len;
}
}
void dele(node *p,int L,int R)
{
if(p->L==L&&p->R==R)
{
p->count--;
if(p->count==0)
{
if(p->L==p->R)
{
p->len=0;
}
else
{
p->len=p->left->len+p->right->len;
}
}
return;
}
int mid=(p->L+p->R)/2;
if(R<=mid)
{
dele(p->left,L,R);
}
else if(L>=mid+1)
{
dele(p->right,L,R);
}
else
{
dele(p->left,L,mid);
dele(p->right,mid+1,R);
}
if(p->count==0)
{
p->len=p->left->len+p->right->len;
}
}
//bool operator==(const li &a,const li &b)
//{
// return a.x==b.x;
//}
int main()
{
int total=1;
int n;
int i;
k=0;
while(scanf("%d",&n),n)
{
nline=0;
printf("Test case #%d\n",total++);
for(i=0;i<n;i++)
{
scanf("%lf %lf %lf %lf",&m[i].up.x,&m[i].up.y,&m[i].down.x,&m[i].down.y);
y[k++]=m[i].up.y;
y[k++]=m[i].down.y;
line[nline].x=m[i].up.x;
line[nline].left=true;
line[nline].y1=m[i].up.y;
line[nline].y2=m[i].down.y;
nline++;
line[nline].x=m[i].down.x;
line[nline].left=false;
line[nline].y1=m[i].up.y;
line[nline].y2=m[i].down.y;
nline++;
}
sort(y,y+k,cmp);//从小到大排序y[0],,,,,y[k-1]...第i个区间为y[i-1]-y[i],共有1,2,,,k-1号区间
k=unique(y,y+k)-y;
nodecount=0;
buildtree(tree,1,k-1);
sort(line,line+nline,cnp);
//nline=unique(line,line+nline)-line;
double res=0;
int L,R;
for(i=0;i<nline-1;i++)
{
if(line[i].left==true)
{
if(line[i].y1>line[i].y2)
{
R=binsearch(line[i].y1)-1;
L=binsearch(line[i].y2);
insert(tree,L,R);
}
else
{
R=binsearch(line[i].y2)-1;
L=binsearch(line[i].y1);
insert(tree,L,R);
}
}
else
{
if(line[i].y1>line[i].y2)
{
R=binsearch(line[i].y1)-1;
L=binsearch(line[i].y2);
dele(tree,L,R);
}
else
{
R=binsearch(line[i].y2)-1;
L=binsearch(line[i].y1);
dele(tree,L,R);
}
}
res+=tree[0].len*(line[i+1].x-line[i].x);
}
printf("Total explored area: %.2f\n\n",res);
}
return 0;
}