hdu1255(求多个面积的交)

跟1264差不多,但是需要注意就是只计算覆盖度大于等于2的长度,要记住修改时要修改所有子节点

3109msC++代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
const int NUM = 2000;
typedef struct line
{
double x,y1,y2;
int flag;
};
typedef struct node
{
int left,mid,right,key;
double len;
}node;
line lines[NUM];
node T[ NUM<<2 ];
double Y[NUM];//存储离散化的纵坐标
void create(int u,int l,int r)
{
T[u].left = l;
T[u].right = r;
T[u].key = 0;
T[u].len = 0.0;
T[u].mid = (l+r)>>1;
if(r == l + 1)
return;
create(u+u,l,T[u].mid);
create(u+u+1,T[u].mid,r);
}
void inquiry(int i)
{
if(T[i].key > 1) //有覆盖
{
T[i].len = Y[T[i].right] - Y[T[i].left];
}
else if (T[i].right - T[i].left == 1)
{
T[i].len = 0.0;
}
// 其他情况
else
{
T[i].len = T[i+i].len + T[i+i+1].len;
}
}
void change(line li,int i)
{
if (Y[T[i].left] == li.y1 && Y[T[i].right] == li.y2)
{
// “左”边flag是1 “右”边flag是-1
// 其实是计算完一个矩形的面积之和,cover减去1
// 就相当于把这个矩形擦除掉了
T[i].key += li.flag;
}
if((T[i].left + 1) < T[i].right)
{
int m = (T[i].left + T[i].right) >> 1;
if (li.y1 >= Y[m])
{
change(li, i+i+1);
}
else if (li.y2 <= Y[m])
{
change(li, i+i);
}
else
{
line ll, lr;
ll.y1 = li.y1;
ll.y2 = Y[m];
ll.flag = li.flag;
lr.y1 = Y[m];
lr.y2 = li.y2;
lr.flag = li.flag;
change(ll, i+i);
change(lr, i+i+1);
}
}
// 每次插入节点后,计算覆盖的长度
inquiry(i);
}
bool cmp(const line& lhs, const line& rhs)
{
return lhs.x < rhs.x;
}
/*读入左竖边时,按左竖边的长度作为高来计算;
读入右竖边时,把右竖边覆盖的Y轴范围释放1,
删除一个与之对应的左竖边对覆盖Y轴的影响,
交给其前面的某个左竖边来确定覆盖范围;*/
int main()
{
double x1,y1,x2,y2;
int n,t,m,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&m);
int i = 1;
for(j = 1; j <= m; j++)
{
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
if (y1 > y2)
{
swap(y1, y2);
}
// 左边的边横坐标是x1,所以x1必须是小的一个
if (x1 > x2)
{
swap(x1, x2);
}
lines[i].x = x1;
lines[i].y1 = y1;
lines[i].y2 = y2;
lines[i].flag = 1;
Y[i++] = y1;
lines[i].x = x2;
lines[i].y1 = y1;
lines[i].y2 = y2;
lines[i].flag = -1;  // 抵消上次的覆盖
Y[i++] = y2;
}
n = i - 1;
sort(Y+1,Y+n+1);
sort(lines+1,lines+n+1,cmp);
create(1,1,n);
change(lines[1],1);
double ans = 0.0;
for(i = 2; i <= n ; i++)
{
ans += T[1].len * (lines[i].x - lines[i-1].x);
change(lines[i],1);
}
printf("%.2lf\n", ans);
}
return 0;
}

 

你可能感兴趣的:(a)