#include<iostream.h>
#include<stdlib.h>
const int MAXN=100;
struct Vsegment{
double x, yb, ye;
bool isLeft;
};
struct StreeNode{
int b, e;
int c;
StreeNode* left;
StreeNode* right;
};
int n;
double x1, y1, x2, y2;
double endpoint[MAXN*2];
Vsegment vseg[MAXN*2];
StreeNode* streeRoot;
double ans;
//创建根为root,起点为b,结点为e的线段树.
void CreateStree(StreeNode* &root, int b, int e);
//删除根为root的线段树,即删除其所有节结点.
void DeleteStree(StreeNode* &root);
//在根为root的线段树中,插入线段[l,r].l和r为endpoint中的元素.
void InsertSegment(StreeNode* root, double l, double r);
//在根为root的线段树中,删除线段[l,r].l和r为endpoint中的元素.
void DeleteSegment(StreeNode* root, double l, double r);
//计算根为root的线段树中所有线段并集的长度并返回.
double GetSegmentLength(StreeNode* root);
//将endpoint中的元素按从小到大的顺序快速排序时的比较函数.
int Comp1(const void* a, const void* b);
//将vseg中的元素按从左到右的顺序快速排序时的比较函数.
int Comp2(const void* a, const void* b);
int main()
{
int t, i, j;
cout.setf(ios::fixed);
cout.precision(2);
t=0;
streeRoot=NULL;
while(cin>>n&&n!=0){
j=0;
for(i=0;i<n;i++){
cin>>x1>>y1>>x2>>y2;
vseg[j].x=x1;
vseg[j].yb=y1;
vseg[j].ye=y2;
vseg[j].isLeft=true;
endpoint[j]=y1;
j++;
vseg[j].x=x2;
vseg[j].yb=y1;
vseg[j].ye=y2;
vseg[j].isLeft=false;
j++;
}
//将endpoint中的元素按照从小到大的顺序快速排序,并去掉其中值相同的元素.
qsort(endpoint,n*2,sizeof(double),Comp1);
j=1;
for(i=1;i<n*2;i++){
if(endpoint[i]!=endpoint[i-1]){
endpoint[j]=endpoint[i];
j++;
}
}
//创建根为streeRoot,起点为0,终点为j-1的线段树.
CreateStree(streeRoot, 0, j-1);
//将vseg中的元素按照从左至右的顺序快速排序.
qsort(vseg,n*2,sizeof(Vsegment),Comp2);
//从左至右进行扫描,求出每一条窄条内要求区域的面积,并累加到ans.
ans=0;
for(i=0;i<n*2-1;i++){
if(vseg[i].isLeft){
InsertSegment(streeRoot,vseg[i].yb,vseg[i].ye);
}
else{
DeleteSegment(streeRoot,vseg[i].yb,vseg[i].ye);
}
ans+=(vseg[i+1].x-vseg[i].x)*GetSegmentLength(streeRoot);
}
//输出结果
t++;
cout<<"Test case #"<<t<<endl;
cout<<"Total explores area:"<<ans<<endl;
cout<<endl;
//删除线段树并将其置为空树.
DeleteStree(streeRoot);
streeRoot=NULL;
}
return 0;
}
void CreateStree(StreeNode* &root, int b, int e)
{
root=new StreeNode();
root->b=b;
root->e=e;
root->c=0;
if(e-b>1){
int mid=(b+e)/2;
CreateStree(root->left,b,mid);
CreateStree(root->right,mid,e);
}
else{
root->left=NULL;
root->right=NULL;
}
}
void DeleteStree(StreeNode* &root)
{
if(root!=NULL){
DeleteStree(root->left);
DeleteStree(root->right);
delete root;
}
}
void InsertSegment(StreeNode* root,double l, double r)
{
if(l<=endpoint[root->b]&& endpoint[root->e]<=r){
root->c++;
}
else{
int mid=(root->b+root->e)/2;
if(l<endpoint[mid]){
InsertSegment(root->left,l,r);
}
if(r>endpoint[mid]){
InsertSegment(root->right,l,r);
}
}
}
void DeleteSegment(StreeNode* root,double l,double r)
{
if(l<=endpoint[root->b]&&endpoint[root->e]<=r){
root->c--;
}
else{
int mid=(root->b+root->e)/2;
if(l<endpoint[mid]){
DeleteSegment(root->left,l,r);
}
if(r>endpoint[mid]){
DeleteSegment(root->right,l,r);
}
}
}
double GetSegmentLength(StreeNode* root)
{
if(root->c>0){
return endpoint[root->e]-endpoint[root->b];
}
if(root->left==NULL){
return 0;
}
return GetSegmentLength(root->left)+GetSegmentLength(root->right);
}
int Comp1(const void* a, const void* b)
{
double x=(*(double*)a), y=(*(double*)b);
if(x>y){
return 1;
}
else if(x<y){
return -1;
}
else{
return 0;
}
}
int Comp2(const void* a, const void* b)
{
double x=((Vsegment*)a)->x, y=((Vsegment*)b)->x;
if(x>y){
return 1;
}
else if(x<y){
return -1;
}
else{
return 0;
}
}