BZOJ4614/UVA1742 Oil 计算几何
传送门
题意:在平面直角坐标系中给出$N$条互不相交的、与$x$轴平行、且在$x$轴上方的线段,每一条线段的价值为其长度。求一条不与$x$轴平行的直线,使得与这条直线相交的线段的价值之和最大,求出这个和。$N \leq 2000 , -10^6 \leq \text{线段两端点横坐标} \leq 10^6 , 1 \leq \text{线段两端点纵坐标} \leq 10^6$
首先我们可以想到:必定存在一条最优的直线,它经过某一条线段的左端点和某条线段的右端点,因为如果某条最优的直线不满足这些性质,我们可以通过旋转和平移使其满足条件。基于上面的结论,我们可以很轻松地想到一种算法:枚举直线经过哪一条线段的左端点和哪一条线段的右端点,然后扫一遍所有的线段看其是否被该直线穿过。这样子的复杂度是$O(n^3)$的。
接着我们考虑优化。我们这样考虑:枚举直线经过其左端点的线段,那么某一条线段会产生贡献当且仅当直线的斜率在某一个区间之内。那么我们将所有线段的会产生贡献的区间算出来,问题就转化为了:给定若干区间,每个区间有权值,选择一个点使得包含这个点的区间的权值之和最大。这个问题可以利用尺取法:按照左端点从小到大加入区间,删除与新加入的区间不相交的区间,计算剩余的权值和。这种算法的复杂度就降为了$O(n^2logn)$
一个细节:为了避免区间不连续、斜率不存在的情况,我们可以计算每一个线段产生贡献时,直线斜率的倒数会落在哪一段区间$($我们认为直线的斜率不存在的时候,斜率的倒数为$0)$,这样每一个线段的贡献区间就是连续的,还可以在计算斜率时避免除$0$。
//一份常数极大的Code
#include<bits/stdc++.h>
#define ld long double
#define eps 1e-12
using namespace std;
inline int read(){
;
;
char c = getchar();
while(!isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
struct range{
ld l , r;
int ind;
}now[] , ano[];
][];
inline long long max(long long a , long long b){
return a > b ? a : b;
}
inline void swap(int &a , int &b){
int t = a;
a = b;
b = t;
}
inline void swap(ld &a , ld &b){
ld t = a;
a = b;
b = t;
}
bool cmp1(range l , range r){
return l.l < r.l;
}
bool cmp2(range l , range r){
return l.r < r.r;
}
inline ld calcK(int x1 , int y1 , int x2 , int y2){
return (ld)(x1 - x2) / (y1 - y2);
}
int main(){
int N;
while(scanf("%d" , &N) != EOF){
; i <= N ; i++){
num[i][] = read();
num[i][] = read();
num[i][] = read();
] < num[i][])
swap(num[i][] , num[i][]);
}
;
; i <= N ; i++){
;
; j <= N ; j++)
] != num[j][]){
now[++cnt].l = calcK(num[i][] , num[i][] , num[j][] , num[j][]);
now[cnt].r = calcK(num[i][] , num[i][] , num[j][] , num[j][]);
now[cnt].ind = j;
if(now[cnt].l > now[cnt].r)
swap(now[cnt].l , now[cnt].r);
now[cnt].l -= eps;
now[cnt].r += eps;
ano[cnt] = now[cnt];
}
sort(now + , now + cnt + , cmp1);
sort(ano + , ano + cnt + , cmp2);
;
] - num[i][];
maxN = max(maxN , ans);
; j <= cnt ; j++){
ans += num[now[j].ind][] - num[now[j].ind][];
while(ano[p].r < now[j].l){
ans -= num[ano[p].ind][] - num[ano[p].ind][];
++p;
}
maxN = max(maxN , ans);
}
}
printf("%lld\n" , maxN);
}
;
}
BZOJ4614/UVA1742 Oil 计算几何的更多相关文章
- BZOJ4614 UVA1742 Oil 计算几何+搜索+扫描线
正解:计算几何+搜索+扫描线 解题报告: 传送门 哇我是真的觉得这题很妙了!各个方面都很妙啊... 首先有一个很重要的结论:最优线一定可以通过各种变换(旋转/平移)使得经过一条线段的左端点(...并不 ...
- BZOJ4614 [Wf2016]Oil
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- HDU5033 building 单调栈+计算几何
正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
- BZOJ 4614 【Wf2016】 Oil
题目链接:Oil 感觉同时几线作战有点吃不消啊-- 这道题有一个显然的结论,那就是最优的直线一定过某条线段的端点. 仔细想想很有道理.如果最终的直线没有过线段的端点的话,那么这条直线就一定可以平移,直 ...
- ACM/ICPC 之 计算几何入门-叉积-to left test(POJ2318-POJ2398)
POJ2318 本题需要运用to left test不断判断点处于哪个分区,并统计分区的点个数(保证点不在边界和界外),用来做叉积入门题很合适 //计算几何-叉积入门题 //Time:157Ms Me ...
- HDU 2202 计算几何
最大三角形 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- ACM 计算几何中的精度问题(转)
http://www.cnblogs.com/acsmile/archive/2011/05/09/2040918.html 计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模 ...
- Oil Deposits
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- hdu 2393:Higher Math(计算几何,水题)
Higher Math Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- putty之pscp上传文件
控制台下打开pscp可执行文件 命令 >pscp -i 证书名 -r 要上传的文件 root@服务器路径:/opt
- spring 开发 Tars
和不使用 Spring 的 tars HelloWord 项目相比,客户端完全一样,服务端两个地方不一样 创建不使用 Spring 的 tars HelloWord 步骤: https://www.c ...
- Chrome_浏览器开发人员工具
Google Chrome 浏览器开发人员工具,让网页开发变得更轻松 无论是 IE 6/7 的 Internet Explorer Developer Toolbar 或者是 IE 8 自带的 Dev ...
- 关于string指针
string str("hello world"); string *pstr = &str; cout << pstr[0] << endl; c ...
- ORM查询之基于对象的正向查询与反向查询
一.为什么有正向查询和反向查询? 举例有两张表,一张表叫书籍表,一张表叫出版社表,他们关系是一对多的关系,书籍是多,出版社是一,因为一本书应该只有一个出版社对应,而出版社可以有多本书对应. 那么在实际 ...
- Visual Stuido插件大全
JS Enhancements 使用JS能像C#代码一样折叠成块 Code Compare Code Compare is a powerful file and folder comparison ...
- SSO阅读有感
SSO比较详细且理解.赞 链接:https://www.cnblogs.com/ywlaker/p/6113927.html
- Jmeter参数化方法
用Jmeter测试时包含两种情况的参数:一种是在url中,一种是请求中需要发送的参数. 设置参数值的方法有如下几种: 一.函数助手 用Jmeter中的函数获取参数值,__Random,__thread ...
- MySQL 聚簇索引和非聚簇索引的认识
聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法.特点是存储数据的顺序和索引顺序一致.一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引. 在<数据库原理&g ...
- Linux 小知识翻译 - 「分区」
安装Linux的时候,需要对硬盘进行分区.那么「分区」到底是什么呢? 「分区」在日语中有区分,分割的意思.计算机术语中有时会说「对一个磁盘进行分区」,整个意思就是指定如何分割磁盘的意思. 「对磁盘进行 ...