O - 覆盖的面积 HDU - 1255

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 

Input

输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000. 

注意:本题的输入数据较多,推荐使用scanf读入数据. 

Output

对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数. 

Sample Input

2
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1

Sample Output

7.63
0.00
#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1010;
struct f
{
	double l, r, h;
	int flag;
}line[MAXN * 2];
struct node
{
	int l, r;
	double one_len, more_len;
	bool ye;
	int lazy;
}tree[MAXN * 8];
double temp[MAXN * 2];

bool com(f u, f v)
{
	return u.h < v.h;
}
void build( int l, int r, int rt )
{
	tree[rt].l = l; tree[rt].r = r;
	tree[rt].one_len = tree[rt].more_len = 0;
	tree[rt].lazy = 0;
	tree[rt].ye = 0;
	if( l + 1 == r )
	{
		tree[rt].ye = 1;
		return;
	}
	int mid = ( l + r ) >> 1;
	build( l, mid, rt << 1 );
	build( mid, r, rt << 1 | 1 );
}
void push(int rt)
{
	if(tree[rt].lazy > 1)
		tree[rt].one_len = tree[rt].more_len = temp[tree[rt].r] - temp[tree[rt].l];
	else if(tree[rt].lazy == 1)
	{
		tree[rt].one_len = tree[rt].more_len = temp[tree[rt].r] - temp[tree[rt].l];;
		if(tree[rt].l + 1 == tree[rt].r)
			tree[rt].more_len = 0;
		else
			tree[rt].more_len = tree[rt << 1].one_len + tree[rt << 1 | 1].one_len;
	}
	else
	{
		if(tree[rt].l + 1 == tree[rt].r)
			tree[rt].one_len = tree[rt].more_len = 0;
		else
		{
			tree[rt].one_len = tree[rt << 1].one_len + tree[rt << 1 | 1].one_len;
			tree[rt].more_len = tree[rt << 1].more_len + tree[rt << 1 | 1].more_len;
		}
	}
}
void update(int x, int y, int l, int r, int rt, int q)
{
	if(l >= x && r <= y)
	{
		tree[rt].lazy += q;
		push(rt);
		return;
	}
	int mid = (l + r) >> 1;
	if(mid > x)
		update(x, y, l, mid, rt << 1, q);
	if(mid < y)
		update(x, y, mid, r, rt << 1 | 1, q);
	push(rt);
}
int main()
{
	int T, n;
	int cas = 0;
	double x1, y1, x2, y2;
	scanf("%d", &T);
	while( T -- )
	{
		scanf("%d", &n);
		cas ++;
		int tot = 0;
		for( int i = 1; i <= n; i ++ )
		{
			scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
			tot ++;
			line[tot].l = x1; line[tot].r = x2;
			line[tot].h = y1; line[tot].flag = 1;
			temp[tot] = x1;
			tot ++;
			line[tot].l = x1; line[tot].r = x2;
			line[tot].h = y2; line[tot].flag = -1;
			temp[tot] = x2;
		}
		sort( temp + 1, temp + tot + 1 );
		sort( line + 1, line + tot + 1, com );
		int k = 1;
		for( int i = 2; i <= tot; i ++ )
		{
			if( temp[i] != temp[i - 1] )
			{
				k ++ ;
				temp[k] = temp[i];
			}
		}
		//cout << k << endl;
		build( 1, k , 1 );
		double ans = 0;
		//for(int i = 1; i <= k ; i ++)
		//	cout << temp[i] << " " ;
		//cout << endl;
		for( int i = 1; i < tot; i ++ )
		{
			int L = lower_bound( temp + 1, temp + k + 1, line[i].l ) - temp;
			int R = lower_bound( temp + 1, temp + k + 1, line[i].r ) - temp;
			//cout << L << " " << R << endl;
			update( L, R, 1, k, 1, line[i].flag );
			//cout << "!" << tree[1].more_len << endl;
			//for(int j = 1; j <= 15 ; j ++)
			//	cout << tree[j].lazy << " " << tree[j].one_len << " " << tree[j].more_len << endl;
			ans += 1.00 * tree[1].more_len * ( line[i + 1].h - line[i].h);
			//cout << "!!" << ans << endl;
		}
		printf("%.2lf\n",ans);

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ant_e_zz/article/details/81431912
今日推荐