您的位置:首页 > 其它

POJ 1177 Picture

2014-03-07 00:15 225 查看
http://poj.org/problem?id=1177

 

典型的求周长并的题目,在学习了面积并之后,酝酿了好几天,终于把这周长并的独立的写出来了,扫描线面积并 周长并归根到底还是线段树的应用。用线段树来维护数据

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#define N 51000
using namespace std;
struct num
{
int x1,y1,x2,y2;
}infor
;
struct Num
{
int x,y1,y2,c;
}line
;
struct tree
{
int l,r,ly,ry,c;
int ch;
}a[4*N];
int b
,n,Ba;
bool cmp(Num p1,Num p2)
{
if(p1.x!=p2.x)
{
return p1.x < p2.x;
}else
{
return p1.c>p2.c;
}
}
int main()
{
//freopen("data.txt","r",stdin);
int f();
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d %d %d %d",&infor[i].x1,&infor[i].y1,&infor[i].x2,&infor[i].y2);
}
int res = 0;
res+=f();
for(int i=1;i<=n;i++)
{
swap(infor[i].x1,infor[i].y1);
swap(infor[i].x2,infor[i].y2);
}
res+=f();
printf("%d\n",res);
}
return 0;
}
void build(int k,int l,int r)
{
a[k].l = l; a[k].r = r;
a[k].c = 0;
a[k].ly = b[l];
a[k].ry = b[r];
a[k].ch = 0;
if(l+1==r)
{
return ;
}
int mid = (l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid,r);
}
void pushup(int k)
{
a[k].ch = a[k<<1].ch+a[k<<1|1].ch+a[k].c;
}
void update(int k,Num p)
{
if(a[k].ly==p.y1&&a[k].ry==p.y2)
{
a[k].c+=p.c;
a[k].ch+=p.c;
return ;
}
if(a[k<<1].ry>=p.y2)
{
update(k<<1,p);
}else if(a[k<<1|1].ly<=p.y1)
{
update(k<<1|1,p);
}else
{
Num e = p;
e.y2 = a[k<<1].ry;
update(k<<1,e);
e = p;
e.y1 = a[k<<1|1].ly;
update(k<<1|1,e);
}
pushup(k);
}
int find(int k,Num p)
{
if(a[k].ly<=p.y1&&a[k].ry>=p.y2&&a[k].ch==0)
{
return 0;
}
if(a[k].ly<=p.y1&&a[k].ry>=p.y2&&a[k].c>0)
{
return p.y2 - p.y1;
}
if(a[k<<1].ry>=p.y2)
{
return find(k<<1,p);
}else if(a[k<<1|1].ly<=p.y1)
{
return find(k<<1|1,p);
}else
{
Num e1 = p;
e1.y2 = a[k<<1].ry;
Num e2 = p;
e2.y1 = a[k<<1|1].ly;
return find(k<<1,e1)+find(k<<1|1,e2);
}
}
int f()
{
int Top = 1;
for(int i=1;i<=n;i++)
{
line[Top].x = infor[i].x1;
line[Top].y1 = infor[i].y1;
line[Top].y2 = infor[i].y2;
line[Top].c = 1;
b[Top++] = infor[i].y1;
line[Top].x  = infor[i].x2;
line[Top].y1 = infor[i].y1;
line[Top].y2 = infor[i].y2;
line[Top].c = -1;
b[Top++] = infor[i].y2;
}
sort(b+1,b+Top);
sort(line+1,line+Top,cmp);
build(1,1,Top-1);
int res = 0;
for(int i=1;i<=Top-1;i++)
{
if(line[i].c==-1)
{
update(1,line[i]);
}
res+=(line[i].y2-line[i].y1-find(1,line[i]));
if(line[i].c==1)
{
update(1,line[i]);
}
}
return res;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: