题意:计算出所有矩形的面积。
主要思路:把图的上下两条边分别赋值为下边为1,上边为-1,这是为了判断用;
先建个树这里的cover是表示区间是否存在,flag表示上下边1或-1,node表示节点,X[l] ~ X[r],这里len就表示有效长度了;Edge表示线段y就是与x轴的高,平行与x轴的线;主要看代码:
struct node
{
int l, r, cover;
double len;
}N[mn<<2];
struct Edge
{
double x1, x2, y;
int flag;
}E[mn<<2];
bool cmp(Edge x, Edge y)
{
return x.y < y.y;
}
void build(int d, int l, int r)
{
N[d].l = l, N[d].r = r, N[d].cover = 0,N[d].len = 0.0;
if (l == r)
return;
int mid = (l + r) >> 1;
build(d<<1,l,mid);
build(d<<1|1,mid+1,r);
}
接下来就是主代码了,缺少点解释以后在补充;
#include
#include
#include
#include
using namespace std;
#define STOP cout << "STOP!~~" << endl;
const int mn = 1005;
int n, m;
double X[mn];
struct node
{
int l, r, cover;
double len;
}N[mn<<2];
struct Edge
{
double x1, x2, y;
int flag;
}E[mn<<2];
bool cmp(Edge x, Edge y)
{
return x.y < y.y;
}
void build(int d, int l, int r)
{
N[d].l = l, N[d].r = r, N[d].cover = 0,N[d].len = 0.0;
if (l == r)
return;
int mid = (l + r) >> 1;
build(d<<1,l,mid);
build(d<<1|1,mid+1,r);
}
int Find(int len,double x)
{
int l = 0, r = len;
while (l <= r)
{
int mid = (l + r) >> 1;
if (X[mid] == x) return mid;
if (X[mid] < x) l = mid + 1;
else r = mid - 1;
}
return -1;
}
void mmp(int d)
{
int l = N[d].l - 1, r = N[d].r;//补回原来的
if (l == r)
N[d].len = 0;
else if (N[d].cover)
{
// cout << X[r] << " " << X[l] << endl;
N[d].len = X[r] - X[l];
}
else
N[d].len = N[d<<1].len + N[d<<1|1].len;
}
void update(int d, int ql, int qr, int flag)
{
int l = N[d].l, r = N[d].r;
if (ql <= l && qr >= r)
{
N[d].cover += flag;
mmp(d);
return;
}
int mid = (l + r) >> 1;
if (mid >= ql) update(d<<1,ql,qr,flag);
if (mid < qr) update(d<<1|1,ql,qr,flag);
mmp(d);
}
int main()
{
int i, j, z, cnt = 1;
double x1, x2, y1, y2;
while (~scanf("%d",&n)&&n)
{
memset(X,0,sizeof(X));
// memset(N,0,sizeof(N));
j = 0;
for (i = 0;i < n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
X[j] = x1;
E[j].x1 = x1, E[j].x2 = x2, E[j].y = y1;
E[j++].flag = 1;
X[j] = x2;
E[j].x1 = x1, E[j].x2 = x2, E[j].y = y2;
E[j++].flag = -1;
}
sort(X,X+j);
sort(E,E+j,cmp);
int k = 1;
for (i = 1;i < j;i++)
{
if (X[i] != X[i-1]) X[k++] = X[i];
}
build(1,1,j);//这从1开始
printf("Test case #%d\n",cnt++);
double ret = 0.0;
for (i = 0;i < j;i++)
{
int l = Find(j,E[i].x1);
int r = Find(j,E[i].x2);
update(1,l+1,r,E[i].flag);//所以这要加1因为是从1开始的
ret += (E[i+1].y - E[i].y)*N[1].len;
}
printf("Total explored area: %.2lf\n\n",ret);
}
return 0;
}