HDU 1542 Atlantis 线段树扫描线求矩形并面积

HDU1542

思路:线段树扫描线模板。
扫描线求矩形并面积大致思路:
从下往上扫的话 ,需要先存下来矩形的上下边,按照y的大小排序,记录每条线段的左右端点l , r 以及高度 y , 下边对应区域就加1,上边减1,每次拿这条线段到下条线段的距离 * 区域总长度累加就是并的总面积。
过程大致就是下面这样,从下往上,遇到上下边就更新,求和。
在这里插入图片描述
本来看完题想着复习重敲下代码的,但是这题我二分找位置的时候用函数调用ME,直接写就AC,一直找不到ME的原因导致我弄了一晚上,想吐早知道不写了。。。。
Code:

#include <bits/stdc++.h>
using namespace std ;
const int AX = 222 ; 
struct Node{
	double l , r , y ;
	int cov ;
	Node(){};
	Node( double l , double r , double y , int cov ):l(l),r(r),y(y),cov(cov){}
	bool operator < ( const Node &ch )const{
		return y < ch.y ;
	} 
}line[AX];
vector<double> X;
double sum[AX<<2] ;
int mark[AX<<2] ; 
int getId( int x ){
	return lower_bound( X.begin() , X.end() , x ) - X.begin() + 1 ; 
}
void pushUp( int rt , int l , int r ){
	if( mark[rt] ) sum[rt] = X[r] - X[l-1] ; // r - 1 + 1 
	else if( l == r ) sum[rt] = 0 ; 
	else sum[rt] = sum[rt<<1] + sum[rt<<1|1]; 
} 

void update( int L , int R , int cov , int l , int r , int rt ){
	if( L <= l && R >= r ){
		mark[rt] += cov ; 
		pushUp( rt , l , r ) ;
		return ; 
	}
	int mid = ( l + r ) >> 1 ; 
	if( L <= mid ) update( L , R , cov , l , mid , rt << 1 ) ;
	if( R > mid ) update( L , R , cov , mid + 1 , r , rt << 1 | 1 ) ; 
	pushUp( rt , l , r ) ;
}

int main(){
	int n ;
	int Case = 0 ; 
	while( scanf("%d",&n) && n ){
		X.clear() ; 
		double x1 , y1 , x2 , y2 ; 
		int num = 0 ; 
		while( n-- ){
			scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
			X.push_back(x1) ; 
			line[num++] = Node( x1 , x2 , y1 , 1 ) ;
			X.push_back(x2) ; 
			line[num++] = Node( x1 , x2 , y2 , -1 ) ;
		}
		sort( line , line + num ) ; 
		sort( X.begin() , X.end() ) ;
		X.erase( unique( X.begin() , X.end() ) , X.end() ) ; 
		int len = X.size() ; 
		double res = 0 ;
		for( int i = 0 ; i < num ; i ++ ){
			int l = lower_bound( X.begin() , X.end() , line[i].l ) - X.begin() + 1;
			int r = lower_bound( X.begin() , X.end() , line[i].r ) - X.begin() + 1 - 1 ;
			/*int l = getId( line[i].l ) ; 
			int r = getId( line[i].r ) - 1 ; */
			update( l , r , line[i].cov , 1 , len , 1 ) ;
			res += sum[1] * ( line[i+1].y - line[i].y ) ;  
		}
		printf("Test case #%d\n",++Case);
		printf("Total explored area: %.2lf\n",res);
		printf("\n");
	}
	return 0 ; 
}


猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/84453553