poj 1151.Atlantis

Atlantis

#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;
	}
} 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值