您的位置:首页 > 其它

poj 1151 poj 1389 线段树+扫描线+离散化 [矩形的面积并]

2014-10-14 10:50 323 查看




Atlantis


题意:求矩形的
面积并


解法:


扫描线+线段树维护+离散化


扫描矩形左右边界,左边为入边,右边为出边,使用线段树维护段中的覆盖长度即可


离散化y坐标,进行线段树的左右边界维护

不同于传统的建树,左树为 [l,mid],右树为[mid,r];//为了相减方便**

//比如 [1,2][2,4],这样的建立方式,当插入[1,4]时,得出的len值为1+2,但是传统的建图[1,2][3,4]得到的len=2


可以参考这个博文对于扫描线的分析yuzhou627

[poj1151.cpp]

#include<iostream>
#include<cstring>
#include <algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 5000+5

#define inf 0x3f3f3f3f
#define INF 0x3FFFFFFFFFFFFFFFLL
#define rep(i,n) for(i=0;i<n;i++)
#define reP(i,n) for(i=1;i<=n;i++)

#define ull unsigned long long
#define ll long long

#define LL(x) x<<1
#define RR(x)  x<<1|1

#define cle(a) memset(a,0,sizeof(a))

using namespace std;
struct Line{//扫描线
double x,upy,downy;
int flag;
Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){}
Line(){}
}line[maxn];
struct node{
int l,r,flag;
double ly,ry,len;
int Mid(){
return (l+r)>>1;
}
}tree[maxn<<2];
double hash[maxn];
bool cmp(Line a,Line b){return a.x<b.x;
}
void build(int rt,int l,int r){
tree[rt].l=l,tree[rt].r=r;
tree[rt].ly=hash[l],tree[rt].ry=hash[r];
tree[rt].flag=0,tree[rt].len=0;
if(tree[rt].l+1==tree[rt].r)return;
int mid=(l+r)>>1;
build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1,
}
void doit(int x){//更新覆盖段
if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly;
else if(tree[x].l+1==tree[x].r)tree[x].len=0;
else tree[x].len=tree[RR(x)].len+tree[LL(x)].len;
}
void update(int rt,Line a){//更新
if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){
tree[rt].flag+=a.flag;
doit(rt);return;
}
if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a);
else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a);
else{
Line temp=a;temp.downy=tree[LL(rt)].ry;
update(LL(rt),temp);
temp=a;temp.upy=tree[RR(rt)].ly;
update(RR(rt),temp);
}
doit(rt);
return;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
int n;
int T=1;
while(cin>>n&&n){
int i;
for(i=1;i<=n;i++){
double a,b,c,d;scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
line[2*i-1]=Line(a,b,d,1);line[2*i]=Line(c,b,d,-1);
hash[2*i-1]=b,hash[2*i]=d;
}
sort(line,line+2*n+1,cmp);sort(hash,hash+1+n*2);
int m=2*n;
build(1,1,m);update(1,line[1]);
double ans=0.0;
for(i=2;i<=m;i++){
ans+=(tree[1].len)*(line[i].x-line[i-1].x);
update(1,line[i]);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",T++,ans);
}
return 0;
}


[poj1389.cpp]

/*************************************************************************
> File Name: poj1389.cpp
> Author: cy
> Mail: 1002@qq.com
> Created Time: 14/10/14 11:02:43
************************************************************************/

#include<iostream>
#include<cstring>
#include <algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 5000+5

#define inf 0x3f3f3f3f
#define INF 0x3FFFFFFFFFFFFFFFLL
#define rep(i,n) for(i=0;i<n;i++)
#define reP(i,n) for(i=1;i<=n;i++)

#define ull unsigned long long
#define ll long long

#define LL(x) x<<1
#define RR(x)  x<<1|1

#define cle(a) memset(a,0,sizeof(a))

using namespace std;
struct Line{//扫描线
double x,upy,downy;
int flag;
Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){}
Line(){}
}line[maxn];
struct node{
int l,r,flag;
double ly,ry,len;
int Mid(){
return (l+r)>>1;
}
}tree[maxn<<2];
double hash[maxn];
bool cmp(Line a,Line b){return a.x<b.x;
}
void build(int rt,int l,int r){
tree[rt].l=l,tree[rt].r=r;
tree[rt].ly=hash[l],tree[rt].ry=hash[r];
tree[rt].flag=0,tree[rt].len=0;
if(tree[rt].l+1==tree[rt].r)return;
int mid=(l+r)>>1;
build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1,
}
void doit(int x){//更新覆盖段
if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly;
else if(tree[x].l+1==tree[x].r)tree[x].len=0;
else tree[x].len=tree[RR(x)].len+tree[LL(x)].len;
}
void update(int rt,Line a){//更新
if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){
tree[rt].flag+=a.flag;
doit(rt);return;
}
if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a);
else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a);
else{
Line temp=a;temp.downy=tree[LL(rt)].ry;
update(LL(rt),temp);
temp=a;temp.upy=tree[RR(rt)].ly;
update(RR(rt),temp);
}
doit(rt);
return;
}
bool getend(double a,double b,double c,double d){
if(a==-1&&b==-1&&c==-1&&d==-1)return true;
return false;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
int i;
double a,b,c,d;
int T=1;
while(true){
while(scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){
if(getend(a,b,c,d)){
break;
}
line[2*T-1]=Line(a,b,d,1);line[2*T]=Line(c,b,d,-1);
hash[2*T-1]=b,hash[2*T]=d;
T++;
}
if(T==1)return 0;
T--;
sort(line,line+2*T+1,cmp);sort(hash,hash+1+T*2);
int m=2*T;
build(1,1,m);update(1,line[1]);
double ans=0.0;
for(i=2;i<=m;i++){
ans+=(tree[1].len)*(line[i].x-line[i-1].x);
update(1,line[i]);
}
printf("%.0f\n",ans);
T=1;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: