您的位置:首页 > 其它

HDU 1542 Atlantis (线段树求矩阵覆盖面积)

2014-06-28 17:14 363 查看
题意:给你n个矩阵求覆盖面积。

思路:看了别人的结题报告

给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1)、(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1;另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1。根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define M 100
#define inf 0x3fffffff
#define maxn 500000*2

struct seg
{
int flag;
double up,down,x;
}line[M*5];
int cmp(seg a,seg b)
{
return a.x<b.x;
}
struct Tree
{
double up,down,x;
int cover;
bool flag;
}tree[M*M];
double y[M*3];//对y进行分割,建树
void build(int id,int l,int r)
{
tree[id].down=y[l];tree[id].up=y[r];
tree[id].flag=false;tree[id].cover=0;tree[id].x=-1;
if(l+1==r)
{
tree[id].flag=true;
return ;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid,r);
}
double insert(int id,double x,double l,double r,int flag)//flag表示为左边还是右边
{
if(tree[id].down>=r||tree[id].up<=l) return 0;
if(tree[id].flag)
{
if(tree[id].cover>0)//递归到了叶子节点
{
double temp_x=tree[id].x;
double ans=(x-temp_x)*(tree[id].up-tree[id].down);
tree[id].x=x;//定位上一次的x
tree[id].cover+=flag;
return ans;
}
else
{
tree[id].cover+=flag;
tree[id].x=x;
return 0;
}
}
double ans1,ans2;
ans1=insert(id*2,x,l,r,flag);
ans2=insert(id*2+1,x,l,r,flag);
return ans1+ans2;
}
int main()
{
int t,ca=1;
while(scanf("%d",&t)&&t)
{
double x1,x2,y1,y2;
int k=0;
for(int i=0;i<t;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
k++;
y[k]=y1;
line[k].down=y1;
line[k].up=y2;
line[k].x=x1;
line[k].flag=1;//1表示左边
k++;
y[k]=y2;
line[k].x=x2;
line[k].down=y1;
line[k].up=y2;
line[k].flag=-1;//-1表示右边
}
sort(y+1,y+k+1);
sort(line+1,line+1+k,cmp);
build(1,1,k);
double ans=0;
for(int i=1;i<=k;i++)
ans+=insert(1,line[i].x,line[i].down,line[i].up,line[i].flag);
printf("Test case #%d\nTotal explored area: %.2f\n\n",ca++,ans);
}
return 0;
}
/*
2
10 10 20 20
15 15 25 25.5
0
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: