hdu 1828 Picture(线段树,扫描线)
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.
InputYour program is to read from standard input. The first line contains the number of rectangles pasted on the wall. In each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates are given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.
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.OutputYour program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.Sample Input
7
-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
Sample Output
228 题解:
扫描线,横着一次,竖着一次,就可以了,
每次是局对值相减,维护一个l,r(这样不需要坐标转化),然后一个cnt表示这条线段被覆盖了多少次,
以及该线段多少区域,被覆盖了多少次,向上更新即可。
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio> #define N 5007
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
} int n,top,ans,minn,maxx;
struct Node
{
int a,b,c,d;
}a[N],cl[N*2]; struct date
{
int l,r,sum,cnt;
void init(){sum=cnt=0;}
}tr[40007]; void build(int p,int l,int r)
{
tr[p].init();tr[p].l=l,tr[p].r=r;
if (l==r) return;
int mid=(l+r)>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
}
bool cmp(Node x,Node y){return x.a<y.a;}
void update(int p)
{
if (tr[p].cnt) tr[p].sum=tr[p].r-tr[p].l+1;
else tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
}
void change(int p,int l,int r,int x,int y,int z)
{
if (l==x&&y==r)
{
tr[p].cnt+=z;
update(p);
return ;
}
int mid=(l+r)>>1;
if (y<=mid) change(p<<1,l,mid,x,y,z);
else if (x>mid) change(p<<1|1,mid+1,r,x,y,z);
else change(p<<1,l,mid,x,mid,z),change(p<<1|1,mid+1,r,mid+1,y,z);
update(p);
}
void solve()
{
build(1,minn,maxx);
sort(cl+1,cl+top+1,cmp);
int last=0;
for (int i=1;i<=top;i++)
{
change(1,minn,maxx,cl[i].b,cl[i].c-1,cl[i].d);
ans+=abs(tr[1].sum-last);
last=tr[1].sum;
}
}
int main()
{
while(~scanf("%d",&n))
{
minn=10000,maxx=-10000;
for (int i=1;i<=n;i++)
{
a[i].a=read(),a[i].b=read(),a[i].c=read(),a[i].d=read();
minn=min(minn,a[i].a),minn=min(minn,a[i].b),minn=min(minn,a[i].c),minn=min(minn,a[i].d);
maxx=max(maxx,a[i].a),maxx=max(maxx,a[i].b),maxx=max(maxx,a[i].c),maxx=max(maxx,a[i].d);
}
for (int i=1;i<=n;i++)
{
cl[++top].a=a[i].b;
cl[top].b=a[i].a,cl[top].c=a[i].c;
cl[top].d=1;
cl[++top].a=a[i].d;
cl[top].b=a[i].a,cl[top].c=a[i].c;
cl[top].d=-1;
}
solve(),top=0;
for (int i=1;i<=n;i++)
{
cl[++top].a=a[i].a;
cl[top].b=a[i].b,cl[top].c=a[i].d;
cl[top].d=1;
cl[++top].a=a[i].c;
cl[top].b=a[i].b,cl[top].c=a[i].d;
cl[top].d=-1;
}
solve();
printf("%d\n",ans);
}
}
hdu 1828 Picture(线段树,扫描线)的更多相关文章
- HDU 1828 Picture (线段树+扫描线)(周长并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...
- HDU 1828 Picture (线段树:扫描线周长)
依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...
- hdu 1828 Picture(线段树 || 普通hash标记)
http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others) Mem ...
- hdu 1828 Picture(线段树轮廓线)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
随机推荐
- Thinkpad x230设置启动顺序
设置可以从CD或者USB启动1.F1进入BIOS,Security → Secure Boot ,设置为:Disabled2.Startup → UEFI/Legacy Boot ,设置为:Both( ...
- Kruskal算法 分类: c/c++ 算法 2014-10-01 17:09 540人阅读 评论(0) 收藏
Kruskal算法计算最小生成树,只与边有关,时间复杂度O(eloge) 步骤: 1.将边按权值递增排序 2.依次取出边加入最小生成树中并保证无环,判断是否成环可利用并查集. 例:http://ac. ...
- Java中的流(3)字符流-Reader和Writer
java中提供了处理以16位的Unicode码表示的字符流的类,即以Reader和Writer 为基类派生出的一系列类. 1.Reader和Writer 这两个类是抽象类,只是提供了一系列用于字符 ...
- Spring Cloud是什么?
[学习笔记] 3)Spring Cloud是什么?马克-to-win@马克java社区:i)Spring Cloud是一个微服务框架,Spring Cloud基于微服务基础框架Netflix进行了up ...
- Hadoop YARN学习之核心概念(2)
Hadoop YARN学习之核心概念(2) 1. Hadoop 2.X YARN引入的新服务 1.1 新的ResourceManager纯碎作为资源调度器,是集群资源的唯一仲裁者: 1.2 用户应用程 ...
- 使用Qt5.7.0 VS2015版本生成兼容XP的可执行程序
版权声明:本文为灿哥哥http://blog.csdn.net/caoshangpa原创文章,转载请标明出处. 一.直接使用VS2012/VS2013/VS2015生成XP兼容的可执行程序 Visua ...
- 合并百度影音的离线数据 with python 2.1 bdv格式的更新
最近百度影音的离线下载文件,格式有新变化. 经过分析,是bdv格式又有新格式,从最初的bdv0001,到bdv.config 的file....,这次更新的格式是直接包含一个片段,其中还有使用guid ...
- [eclipse]的快捷键的设置
今天新解压了一个eclipse,发现alt+/提示的快捷键不好用了,开始比较犯懒,但是发现开发效率低下,总结几个eclipse下快捷方式的解决办法. 第一个解决没有一点提示的情况. 1.首先通过菜单打 ...
- chatops--rocketchat+hubot
chatops--rocketchat+hubot 原文地址:http://www.cnblogs.com/caoguo/p/7221956.html 先放几张图 # rocket.chat # hu ...
- 对称加密DES加密
DES加密: des是对称加密,加密和解密需要相同的秘钥,它的密码最长56位,必须是8的倍数,秘钥越长,越安全. package com.trm.util.encrypt; import java.s ...