「USACO5.5」矩形周长Picture
题目描述
墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。
编写一个程序计算周长。

如图1所示7个矩形。

如图2所示,所有矩形的边界。所有矩形顶点的坐标都是整数。
输入输出格式
输入格式:
输入文件的第一行是一个整数\(N(0<=N<5000)\),表示有多少个矩形。接下来\(N\)行给出了每一个矩形左下角坐标和右上角坐标(所有坐标的数值范围都在\(-10000\)到\(10000\)之间)。
输出格式:
输出文件只有一个正整数,表示所有矩形的周长。
基本思路
解决这一类平面矩形面积/周长并的方法,还是用最经典的方法(见下)吧。
毕竟这是一道模板题。。。
大佬们都解释了很多了,蒟蒻就不再赘述了(我才不会告诉你我不会讲)
扫描线\(+\)线段树
大体模板应该都差不太多:
扫描一次,从下往上,顺便记录路上的y轴方向的线段长,往\(ans\)中累加就好了。
细节注意事项
第一次交的时候莫名WA最后一个点,很是不解,翻了翻大佬的题解,才发现:
bool cmp(edge a,edge b){return a.h<b.h;}
这是我第一次交时写的cmp函数。
bool cmp(edge a,edge b){return a.h<b.h||(a.h==b.h&&a.f>b.f);}
这是AC时的cmp函数。
对于遇到的重合的一条上边和一条下边(当然不会在同一个矩形内),我们优先处理下边的信息。
参考代码
下面就是本蒟蒻的AC代码,有什么不当或可以改进的地方欢迎大佬来指教%%%
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define rg register
using namespace std;
const int MAXN=5010;
const int MAXM=20010;
const int INF=2147483647;
inline int read(){
int s=0;bool f=false;char c=getchar();
while(c<'0'||c>'9')f|=(c=='-'),c=getchar();
while(c>='0'&&c<='9')s=(s<<3)+(s<<1)+(c^48),c=getchar();
return (f)?(-s):(s);
}
struct node{
int l,r,cnt;
int numx,numy;
bool lf,rf;
}c[MAXM<<2];
#define lson rt<<1
#define rson rt<<1|1
inline void pushup(int rt){
if(c[rt].cnt){
c[rt].numx=c[rt].r-c[rt].l+1;
c[rt].lf=c[rt].rf=true;
c[rt].numy=1;
}
else if(c[rt].l==c[rt].r){
c[rt].numx=0;
c[rt].numy=0;
c[rt].lf=c[rt].rf=false;
}
else{
c[rt].numx=c[lson].numx+c[rson].numx;
c[rt].lf=c[lson].lf;
c[rt].rf=c[rson].rf;
c[rt].numy=c[lson].numy+c[rson].numy-(c[lson].rf&c[rson].lf);
}
}
inline void build(int rt,int l,int r){
c[rt].l=l;
c[rt].r=r;
c[rt].cnt=0;
c[rt].numx=0;
c[rt].numy=0;
c[rt].lf=false;
c[rt].rf=false;
if(l==r) return;
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
}
inline void update(int rt,int l,int r,int v){
if(l<=c[rt].l&&c[rt].r<=r)
return c[rt].cnt+=v,pushup(rt);
int mid=(c[rt].l+c[rt].r)>>1;
if(l<=mid)update(lson,l,r,v);
if(r>mid) update(rson,l,r,v);
pushup(rt);
}
struct edge{int l,r,h,f;}e[MAXN<<1];
bool cmp(edge a,edge b){
return a.h<b.h||(a.h==b.h&&a.f>b.f);
}
int main(){
int n=read(),tot=0;
int maxl=INF,maxr=-INF;
for(rg int i=1;i<=n;i++){
int x1=read(),y1=read();
int x2=read(),y2=read();
maxl=min(maxl,min(x1,x2));
maxr=max(maxr,max(x1,x2));
e[++tot]=(edge){x1,x2,y1,1};
e[++tot]=(edge){x1,x2,y2,-1};
}
sort(e+1,e+tot+1,cmp);
long long ans=0,last=0;
build(1,maxl,maxr-1);
for(rg int i=1;i<=tot;i++){
update(1,e[i].l,e[i].r-1,e[i].f);
ans+=labs(c[1].numx-last);
ans+=(e[i+1].h-e[i].h)*2*c[1].numy;
last=c[1].numx;
}
printf("%lld\n",ans);
return 0;
}
完结撒花 \(qwq\)
「USACO5.5」矩形周长Picture的更多相关文章
- P1856 [USACO5.5]矩形周长Picture
P1856 [USACO5.5]矩形周长Picture $len$ $sum$ $num$ $flag\_l$ $flage\_ ...
- P1856 [USACO5.5]矩形周长Picture[扫描线]
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- 洛谷P1856 [USACO5.5]矩形周长Picture
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- luogu1856 [USACO5.5]矩形周长Picture
看到一坨矩形就要想到扫描线.(poj atantis) 我们把横边竖边分开计算,因为横边竖边其实没有区别,以下论述全为考虑竖边的. 怎样统计一个竖边对答案的贡献呢?答:把这个竖边加入线段树,当前的总覆 ...
- [USACO5.5] 矩形周长Picture
https://www.luogu.org/problemnew/show/P1856 1.每个矩形由两条横向边和两条纵向边组成. 2.对于横向边,按纵坐标排序.设当前讨论的边为 A [s , t] ...
- Luogu P1856 [USACO5.5]矩形周长Picture
线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...
- [题解]P1856 [USACO5.5]矩形周长Picture
Loli 考试的题目之一 题目地址 \(N^2\)做法 #include <cstdio> #include <cstring> #define re register #de ...
- Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)
对于横轴,加上与上一次扫描的差值:对于竖轴,加上高度差与区间内不相交线段\(*2\)的积: 难点在pushdown,注意维护覆盖关系.再就注意负数 #include <iostream> ...
随机推荐
- python做批量剪切、旋转等小程序
我自己在学习python时自己动手做了几个简单实用的小程序,对大家做图像的增强很有效果,我包括我的同学目前都在用我的小程序来做图像增强,非常的实用.话不多说上代码: import globimport ...
- 计算几何-RC-poj2187
This article is made by Jason-Cow.Welcome to reprint.But please post the article's address. 今天学习一下旋( ...
- java 子线程异常处理
如何在父线程中捕获来自子线程的异常呢 方法一:子线程中try... catch... 方法二:为线程设置异常处理器UncaughtExceptionHandler (异常处理也是在子线程中执行,相当于 ...
- 更改mysql数据库默认的字符集(编码方式)
mysql数据库的默认编码方式是latin1, 在mysql中存储和显示中文时会产生乱码,必须要更改默认的编码方式为utf8 或 gbk.(以下以gbk为例.) 更改服务器的编码方式,在终端输入以下命 ...
- Java日期时间API系列21-----Jdk8中java.time包中的新的日期时间API类,xk-time时间转换,计算,格式化,解析的工具
通过工作之余,对Java8中java.time包源码的不断学习,使用和总结,开发了xk-time,初步完成,欢迎试用和提出建议! xk-time xk-time is a datetime conve ...
- js 页面滚动到指定位置
当页面的长度比较长时,如果进行刷新页面,我们希望能够在刷新完成页面之后,能够停留在当前位置,而不是从头再手动滚动到当前位置. 那么这样的效果如何实现呢?下面开始简单描写(由于博客园不支持效果展示,所以 ...
- spring 基于XML的申明式AspectJ通知的执行顺序
spring 基于XML的申明式AspectJ通知的执行顺序 关于各种通知的执行顺序,结论:与配置文件中的申明顺序有关 1. XML文件配置说明 图片来源:<Java EE企业级应用开发教程&g ...
- python中文本的读写操作
文本的操作 函数的排序操作: def func(i): return i[2] list=[('曹操',101,'c'),('吕布',100,'d'),('刘备',200,'l'),('大乔',50, ...
- Django ORM 常用的13个方法
介绍一个可以以py脚本方式运行ORM操作的方法: 可在项目内新建个py文件,复制项目内manage.py文件中的以下代码: if __name__ == "__main__": o ...
- Windows10下修改pip源
pip修改源 写在前面 当我们在使用pip的时候,有些时候会觉得pip安装第三方库的时候速度慢得让人抓狂,那是因为pip是从国外的网站下载东西所以呢下载速度很慢,为了方便我们下载,我们可以通过来修改p ...