题目大意是对给定的很多矩形,求出面积和,重叠的部分只能算一次
可以对x和y坐标进行离散化,然后对面积进行划分,划分成四部分,左上,右上,左下,右下
与之前的线段式线段树不同的是,每次对宽和高进行等分的时侯,xmid和ymid在各部分出现的时候不用+1,因为这里算的是面积,面积是连续的
注意浮点数的判断大小
对于x,y是否相等,只有在x+0.000001 > y && x - 0.000001 < y时成立
对于x<y,只有在x+ 0.000001 < y时成立
对于x<=y,只有在x-0.000001 <y时成立
我的代码
#include<stdio.h>
struct Node
{
int left;
int right;
int up;
int down;
double area;
int flag;
}node[1000001];
double x[201], y[201];
int xnum, ynum;
double area[101][4];
int n;
double Max(double a, double b)
{
return a > b ? a : b;
}
double Min(double a, double b)
{
return a < b ? a : b;
}
bool smaller(double a, double b)
{
if(a - 0.000001 < b)
return 1;
return 0;
}
bool biger(double a, double b)
{
if(a + 0.000001 > b)
return 1;
return 0;
}
int equal(double a, double b)
{
if(a + 0.000001 >= b && a - 0.000001 <= b)
return 1;
return 0;
}
int sort(double *array, int& num)
{
int i, j;
for(i = 1; i < num; i ++)
{
for(j = i + 1; j <= num; j ++)
{
if(equal(array[i], array[j]))
{
array[j] = array[num];
num --;
j --;
}
}
}
for(i = 1; i < num; i ++)
for(j = i + 1; j <= num; j ++)
{
if(array[i] > array[j])
{
array[i] += array[j];
array[j] = array[i] - array[j];
array[i] = array[i] - array[j];
}
}
return 0;
}
int build(int xleft, int xright, int yup, int ydown, int pre)
{
node[pre].left = xleft;
node[pre].right = xright;
node[pre].up = yup;
node[pre].down = ydown;
node[pre].area = 0;
node[pre].flag = 0;
if((xleft + 1 == xright || xleft == xright) && (ydown + 1 == yup || ydown == yup))
return 1;
int xmid = (xleft + xright) / 2, ymid = (yup + ydown) / 2;
build(xleft, xmid, yup, ymid, pre * 4);
build(xmid, xright, yup, ymid, pre * 4 + 1);
build(xleft, xmid, ymid, ydown, pre * 4 + 2);
build(xmid, xright, ymid, ydown, pre * 4 + 3);
return 0;
}
int overlay(double l, double r, double u, double d, double l1, double r1, double u1, double d1, double *over)
{
if(smaller(r, l1) || biger(l, r1) || smaller(u, d1) || biger(d, u1))
{
return 0;
}
over[0] = Max(l, l1);
over[1] = Min(r, r1);
over[2] = Min(u, u1);
over[3] = Max(d, d1);
if(smaller(over[1], over[0]))
return 0;
if(smaller(over[2], over[3]))
return 0;
return 1;
}
int insert(double l, double r, double u, double d, int pre)
{
double over[4];
if(equal(l, x[node[pre].left]) && equal(r, x[node[pre].right]) && equal(u, y[node[pre].up]) && equal(d, y[node[pre].down]))
{
node[pre].area = (u - d) * (r - l);
node[pre].flag = 1;
return 0;
}
if(!node[pre * 4].flag && overlay(l, r, u, d, x[node[pre * 4].left], x[node[pre * 4].right], y[node[pre * 4]. up], y[node[pre * 4].down], over))
{
insert(over[0], over[1], over[2], over[3], pre * 4);
}
if(!node[pre * 4 + 1].flag && overlay(l, r, u, d, x[node[pre * 4 + 1].left], x[node[pre * 4 + 1].right], y[node[pre * 4 + 1]. up], y[node[pre * 4 + 1].down], over))
{
insert(over[0], over[1], over[2], over[3], pre * 4 + 1);
}
if(!node[pre * 4 + 2].flag && overlay(l, r, u, d, x[node[pre * 4 + 2].left], x[node[pre * 4 + 2].right], y[node[pre * 4 + 2]. up], y[node[pre * 4 + 2].down], over))
{
insert(over[0], over[1], over[2], over[3], pre * 4 + 2);
}
if(!node[pre * 4 + 3].flag && overlay(l, r, u, d, x[node[pre * 4 + 3].left], x[node[pre * 4 + 3].right], y[node[pre * 4 + 3]. up], y[node[pre * 4 + 3].down], over))
{
insert(over[0], over[1], over[2], over[3], pre * 4 + 3);
}
node[pre].area = node[pre * 4].area + node[pre * 4 + 1].area + node[pre * 4 + 2].area + node[pre * 4 + 3].area;
return 0;
}
int main()
{
int i, ca = 0;
while(scanf("%d", &n) != EOF && n != 0)
{
xnum = 0;
ynum = 0;
for(i = 1; i <= n; i ++)
{
scanf("%lf%lf%lf%lf", &area[i][0], &area[i][1], &area[i][2], &area[i][3]);
x[++ xnum] = area[i][0];
x[++ xnum] = area[i][2];
y[++ ynum] = area[i][1];
y[++ ynum] = area[i][3];
}
sort(x, xnum);
sort(y, ynum);
build(1, xnum, ynum, 1, 1);
for(i = 1; i <= n; i ++)
{
insert(area[i][0], area[i][2], area[i][3], area[i][1], 1);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++ ca, node[1].area);
}
return 0;
}