扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]
学习链接:http://blog.csdn.net/lwt36/article/details/48908031
学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题。
扫描线求矩形周长并
hdu 1928
Picture
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4795 Accepted Submission(s): 2339
Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.
The corresponding boundary is the whole set of line segments drawn in Figure 2.
The vertices of all rectangles have integer coordinates.
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Please process to the end of file.
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define clr(x) memset(x,0,sizeof(x))
#define MAXN 50010
using namespace std;
struct edgx
{
int l,u,x;
int d;
}edgex[MAXN];
struct edgy
{
int l,r,y;
int d;
}edgey[MAXN];
struct seg
{
int l,r,cov,len;
}segt[MAXN<<];
int cntx,cnty;
int x[MAXN],y[MAXN],vec[MAXN];
bool cmpy(edgy a,edgy b)
{
if(a.y==b.y) return a.d>b.d;
return a.y<b.y;
}
bool cmpx(edgx a,edgx b)
{
if(a.x==b.x) return a.d>b.d;
return a.x<b.x;
}
void init(int i,int l,int r)
{
segt[i]=(seg){l,r,,};
if(l==r)
return ;
int mid=(l+r)>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
return ;
}
void pushup(int i)
{
if(segt[i].cov)
{
segt[i].len=vec[segt[i].r+]-vec[segt[i].l];
}
else if(segt[i].l==segt[i].r)
{
segt[i].len=;
}
else
{
segt[i].len=segt[i<<].len+segt[i<<|].len;
}
return ;
}
void update(int i,int l,int r,int value)
{
if(segt[i].l>=l && segt[i].r<=r)
{
segt[i].cov+=value;
pushup(i);
return ;
}
int mid=(segt[i].l+segt[i].r)>>;
if(mid>=r)
{
update(i<<,l,r,value);
}
else if(mid<l)
{
update(i<<|,l,r,value);
}
else
{
update(i<<,l,r,value);
update(i<<|,l,r,value);
}
pushup(i);
return ;
}
int main()
{
int x1,x2,y1,y2,n,m,T,ans,l,r,k;
while(scanf("%d",&n)!=EOF)
{
cntx=;
cnty=;
for(int i=;i<=n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
edgex[++cntx]=(edgx){y1,y2,x1,};
x[cntx]=x1;
edgex[++cntx]=(edgx){y1,y2,x2,-};
x[cntx]=x2;
edgey[++cnty]=(edgy){x1,x2,y1,};
y[cnty]=y1;
edgey[++cnty]=(edgy){x1,x2,y2,-};
y[cnty]=y2;
}
n<<=;
ans=;
memcpy(vec,x,sizeof(x));
sort(vec+,vec+n+);
m=unique(vec+,vec+n+)-vec-;
sort(edgey+,edgey+n+,cmpy);
init(,,m);
for(int i=;i<=n;i++)
if(edgey[i].l<edgey[i].r)
{
k=segt[].len;
l=lower_bound(vec+,vec+m+,edgey[i].l)-vec;
r=lower_bound(vec+,vec+m+,edgey[i].r)-vec;
update(,l,r-,edgey[i].d);
ans+=abs(segt[].len-k);
}
memcpy(vec,y,sizeof(y));
sort(vec+,vec+n+);
m=unique(vec+,vec+n+)-vec-;
sort(edgex+,edgex+n+,cmpx);
init(,,m);
for(int i=;i<=n;i++)
if(edgex[i].l<edgex[i].u)
{
k=segt[].len;
l=lower_bound(vec+,vec+m+,edgex[i].l)-vec;
r=lower_bound(vec+,vec+m+,edgex[i].u)-vec;
update(,l,r-,edgex[i].d);
ans+=abs(segt[].len-k);
}
printf("%d\n",ans);
}
return ;
}
hdu 1255 矩阵面积交
覆盖的面积
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5718 Accepted Submission(s): 2854
注意:本题的输入数据较多,推荐使用scanf读入数据.
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1
0.00
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define clr(x) memset(x,0,sizeof(x))
#define MAXN 10010
using namespace std;
struct edg
{
double l,r,y;
int d;
}edge[MAXN];
struct seg
{
int l,r,cov;
double len1,len2;
}segt[MAXN<<];
int cnt;
double x[MAXN];
bool cmp(edg a,edg b)
{
if(a.y==b.y) return a.d>b.d;
return a.y<b.y;
}
double max(double a,double b)
{
return a>b?a:b;
}
void init(int i,int l,int r)
{
segt[i]=(seg){l,r,,,};
if(l==r)
return ;
int mid=(l+r)>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
return ;
}
void pushup(int i)
{
if(segt[i].cov>=)
{
segt[i].len2=segt[i].len1=x[segt[i].r+]-x[segt[i].l];
}
else if(segt[i].cov==)
{
segt[i].len1=x[segt[i].r+]-x[segt[i].l];
if(segt[i].l==segt[i].r)
segt[i].len2=;
else
segt[i].len2=max(segt[i<<].len1,segt[i<<].len2)+max(segt[i<<|].len1,segt[i<<|].len2);
}
else
{
if(segt[i].l==segt[i].r)
{
segt[i].len1=segt[i].len2=;
}
else
{
segt[i].len2=segt[i<<].len2+segt[i<<|].len2;
segt[i].len1=segt[i<<].len1+segt[i<<|].len1;
}
}
return ;
}
void update(int i,int l,int r,int value)
{
if(segt[i].l>=l && segt[i].r<=r)
{
segt[i].cov+=value;
pushup(i);
return ;
}
int mid=(segt[i].l+segt[i].r)>>;
if(mid>=r)
{
update(i<<,l,r,value);
}
else if(mid<l)
{
update(i<<|,l,r,value);
}
else
{
update(i<<,l,r,value);
update(i<<|,l,r,value);
}
pushup(i);
return ;
}
int main()
{
int T,n,m,k,u,v;
double x1,x2,y1,y2,ans,l,r;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
cnt=;
ans=;
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
edge[++cnt]=(edg){x1,x2,y1,};
x[cnt]=x1;
edge[++cnt]=(edg){x1,x2,y2,-};
x[cnt]=x2;
}
n<<=;
sort(x+,x+n+);
m=unique(x+,x+n+)-x-;
sort(edge+,edge+n+,cmp);
init(,,m);
for(int i=;i<n;i++)
if(edge[i].r>edge[i].l)
{
l=lower_bound(x+,x+m+,edge[i].l)-x;
r=lower_bound(x+,x+m+,edge[i].r)-x;
update(,l,r-,edge[i].d);
ans+=segt[].len2*(edge[i+].y-edge[i].y);
}
printf("%0.2lf\n",ans);
}
return ;
}
hdu 1542 [POJ 1151] 区间面积并
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12537 Accepted Submission(s): 5257
The input file is terminated by a line containing a single 0. Don’t process it.
Output a blank line after each test case.
10 10 20 20
15 15 25 25.5
0
Total explored area: 180.00
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define clr(x) memset(x,0,sizeof(x))
#define MAXN 10010
using namespace std;
struct edg
{
double l,r,y;
int d;
}edge[MAXN];
struct seg
{
int l,r,cov;
double len;
}segt[MAXN<<];
int cnt;
double x[MAXN];
bool cmp(edg a,edg b)
{
if(a.y==b.y) return a.d>b.d;
return a.y<b.y;
}
double max(double a,double b)
{
return a>b?a:b;
}
void init(int i,int l,int r)
{
segt[i]=(seg){l,r,,};
if(l==r)
return ;
int mid=(l+r)>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
return ;
}
void pushup(int i)
{
if(segt[i].cov)
{
segt[i].len=x[segt[i].r+]-x[segt[i].l];
}
else if(segt[i].l==segt[i].r)
{
segt[i].len=;
}
else
{
segt[i].len=segt[i<<].len+segt[i<<|].len;
}
return ;
}
void update(int i,int l,int r,int value)
{
if(segt[i].l>=l && segt[i].r<=r)
{
segt[i].cov+=value;
pushup(i);
return ;
}
int mid=(segt[i].l+segt[i].r)>>;
if(mid>=r)
{
update(i<<,l,r,value);
}
else if(mid<l)
{
update(i<<|,l,r,value);
}
else
{
update(i<<,l,r,value);
update(i<<|,l,r,value);
}
pushup(i);
return ;
}
int main()
{
int T,n,m,k,u,v;
double x1,x2,y1,y2,ans,l,r;
int kase=;
while(scanf("%d",&n) && n!=)
{
printf("Test case #%d\n",++kase);
cnt=;
ans=;
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
edge[++cnt]=(edg){x1,x2,y1,};
x[cnt]=x1;
edge[++cnt]=(edg){x1,x2,y2,-};
x[cnt]=x2;
}
n<<=;
sort(x+,x+n+);
m=unique(x+,x+n+)-x-;
sort(edge+,edge+n+,cmp);
init(,,m);
for(int i=;i<n;i++)
if(edge[i].r>edge[i].l)
{
l=lower_bound(x+,x+m+,edge[i].l)-x;
r=lower_bound(x+,x+m+,edge[i].r)-x;
update(,l,r-,edge[i].d);
ans+=segt[].len*(edge[i+].y-edge[i].y);
}
printf("Total explored area: %0.2lf\n",ans);
printf("\n");
}
return ;
}
扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]的更多相关文章
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 1542 & & poj 1151
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542/POJ 1151 Atlantis (scaning line + segment tree)
A template of discretization + scaning line + segment tree. It's easy to understand, but a little di ...
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- HDU 1255 覆盖的面积(线段树+扫描线)
题目地址:HDU 1255 这题跟面积并的方法非常像,仅仅只是须要再加一个变量. 刚開始我以为直接用那个变量即可,仅仅只是推断是否大于0改成推断是否大于1.可是后来发现了个问题,由于这个没有下放,没延 ...
- hdu 1255 覆盖的面积(线段树 面积 交) (待整理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. In ...
- hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
了校赛,还有什么途径可以申请加入ACM校队? 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- “三巨头”有变化,BAT还能走多久?
在腾讯市值超越阿里巴巴后,市场分析多数认为,当年的BAT“三巨头”时代已经彻底结束,进入了“双寡头”时代了 从对外投资来看,BAT不同的投资逻辑可以推测其战略方向 撰文/梁云风 时评员,关注财经与互联 ...
随机推荐
- 【LA】5135 Mining Your Own Business
[算法]点双连通分量 [题解]详见<算法竞赛入门竞赛入门经典训练指南>P318-319 细节在代码中用important标注. #include<cstdio> #includ ...
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- cocos2dx 某缩放的页面 CCTableView最后一个标签无法点中
有一个二级界面,在ipad4下面放大到1.6倍,直接对最外层的CCLayer缩放的,里面包含有CCTableView.结果运行的时候无法选中到最后一个标签,无论总的标签是2个还是更多,单步调试,发现到 ...
- 微信小程序setData子元素
页面的数据中如果有子元素,如下图nowQuestion中的deleted元素 在小程序的setData中,不能直接用nowQuestion.deleted来设定它的值,而需要再定义一个变量承接 另外, ...
- 对象方法、类方法、原型方法 && 私有属性、公有属性、公有静态属性
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- DirectX介绍(转)
原文转自 https://baike.baidu.com/item/Direct3D/910353
- Vue组件-使用插槽分发内容
在使用组件时,我们常常要像这样组合它们: <app> <app-header></app-header> <app-footer></app-fo ...
- defconfig file 的 位置
Platform MSM8917 MSM8937 defconfig file position Android/kernel/msm-3.18/arch/arm/configs/
- Python基础===使用virtualenv创建一个新的运行环境
virtualenv简直是一个神器,以ubuntu环境为例, 先安装virtualenv 然后执行如下命令: 多版本创建env的方式: virtualenv 虚拟环境文件目录名 python=pyth ...
- 【UOJ#9】vfk的数据
我感觉这题可以出给新高一玩2333 #include<bits/stdc++.h> #define N 10005 using namespace std; string s[N]; in ...