题目描述

分析:
直角坐标系内,有n条直线分布,求:最大值(对于任意x,直线上能取到的max( f(x) ))构成的折线由哪些直线构成。

Solution :
把直线按照斜率从小到大排序。
从左到右:先找到中斜率最小的直线 r ,它一定属于ans的集合,找到这条直线与所有直线中横坐标最小的点(x0,y0),由x0确定下一条直线 tar(由于可能出现几条直线交 r 于同一点的情况,取这些直线中斜率最大的。)
根据这样的步骤循环找ans,直到当前直线 r 没有与其他直线的交点了为止。
O(n2)的复杂度,要加优化:
因为排了序,而且直线的斜率必须由小到大,所以,当当前直线 r 找交点的时候,可以不用考虑斜率小于这条直线的线了,由于当前找到的直线是不确定,所以只有时间上限 O(n2)

代码不好看啊,当时写的时候分了斜率大于0小于0两部分,其实没必要。

推荐一个blogby Liu Junhao

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 50000
#define MAXM 500000
#define INF 2147483646
const double eps=1e-30;struct node{int a,b,id;
}s[MAXN+10],t[MAXN+10];int n,cnts,cntt,c[MAXM*2+10][2],d[MAXM*2+10][2];
bool ans[MAXN+10];bool cmp(node x,node y){if(x.a==y.a) return x.b>y.b;return x.a<y.a;
}
void read()
{int x,y;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&x,&y);if(x<0){if(c[x+MAXM][1]){if(c[x+MAXM][0]<y)c[x+MAXM][0]=y,c[x+MAXM][1]=i;}elsec[x+MAXM][0]=y,c[x+MAXM][1]=i;}else{if(d[x+MAXM][1]){if(d[x+MAXM][0]<y)d[x+MAXM][0]=y,d[x+MAXM][1]=i;}elsed[x+MAXM][0]=y,d[x+MAXM][1]=i;}}//去掉斜率相同的直线不仅可以优化一小下下,最重要的是避免后面算交点的时候出错(出现除数为0)for(int i=0;i<=MAXM*2;i++){if(c[i][1]){s[++cnts].a=i-MAXM,s[cnts].b=c[i][0];s[cnts].id=c[i][1];}if(d[i][1]){t[++cntt].a=i-MAXM,t[cntt].b=d[i][0];t[cntt].id=d[i][1];}}
}int main()
{read();sort(s+1,s+cnts+1,cmp);sort(t+1,t+cntt+1,cmp);int r,p,q;bool last;if(cnts){r=1,p=2,q=1,last=false;ans[s[r].id]=true;}else{r=1,p=1,q=2,last=true;ans[t[r].id]=true;}double X=-INF;while(true){int tar=-1;double x0=INF,tmp;bool flag=false;for(int k=p;k<=cnts;k++){tmp=1.0*(s[k].b-s[r].b)/(s[r].a-s[k].a);if(tmp>=X&&tmp<=x0){if(fabs(tmp-x0)<=eps){if(tar!=-1&&s[k].a<s[tar].a)continue;}tar=k;x0=tmp;}}for(int k=q;k<=cntt;k++){if(last)tmp=1.0*(t[k].b-t[r].b)/(t[r].a-t[k].a);elsetmp=1.0*(t[k].b-s[r].b)/(s[r].a-t[k].a);if(tmp>=X&&tmp<=x0){if(fabs(tmp-x0)<=eps){if(tar!=-1&&t[k].a<t[tar].a)continue;}tar=k;flag=true;x0=tmp;}}if(tar==-1)break;if(!flag){if(x0==X) ans[s[r].id]=false;else X=x0;ans[s[tar].id]=true,r=tar;p=tar+1;}else{if(x0==X){if(!last) ans[s[r].id]=false;else ans[t[r].id]=false;}else X=x0;ans[t[tar].id]=true,r=tar;p=cnts+1,q=tar+1;}last=flag;}for(int i=1;i<=n;i++)if(ans[i])printf("%d ",i);
}

转载于:https://www.cnblogs.com/katarinayuan/p/6572834.html

HYSBZ/BZOJ 1007 [HNOI2008] 水平可见直线 - 计算几何相关推荐

  1. bzoj 1007 : [HNOI2008]水平可见直线 计算几何

    题目链接 给出n条直线, 问从y轴上方向下看, 能看到哪些直线, 输出这些直线的编号. 首先我们按斜率排序, 然后依次加入一个栈里面, 如果刚加入的直线, 和之前的那条直线斜率相等, 那么显然之前的会 ...

  2. bzoj 1007: [HNOI2008]水平可见直线

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 7378  Solved: 2829 [Submit][S ...

  3. BZOJ.1007.[HNOI2008]水平可见直线(凸壳 单调栈)

    题目链接 可以看出我们是要维护一个下凸壳. 先对斜率从小到大排序.斜率最大.最小的直线是一定会保留的,因为这是凸壳最边上的两段. 维护一个单调栈,栈中为当前可见直线(按照斜率排序). 当加入一条直线l ...

  4. BZOJ 1007 [HNOI2008]水平可见直线 ——半平面交 凸包

    发现需要求一个下凸的半平面上有几个交点. 然后我们把它变成凸包的问题. 好写.好调.还没有精度误差. #include <map> #include <ctime> #incl ...

  5. BZOJ1007:[HNOI2008]水平可见直线(计算几何)

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...

  6. bzoj1007[HNOI2008]水平可见直线

    bzoj1007[HNOI2008]水平可见直线 题意: 平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.给出n条直线 ...

  7. [BZOJ1007](HNOI2008)水平可见直线(半平面交习题)

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.     例如,对于直线:   ...

  8. _bzoj1007 [HNOI2008]水平可见直线【单调栈】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1007 按斜率排序,去掉斜率相同时,截距较小的直线(即只保留该斜率下截距最大的直线).若当前直 ...

  9. [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线:L1:y=x ...

最新文章

  1. 用Remoting 实现一个文件传输组件
  2. 网络:IP协议与寻址
  3. LinkedList源码学习
  4. 设计模式学习笔记(5) - 策略模式
  5. 【2018.1.14】关于本蒟蒻
  6. 使用本机IP调试web项目
  7. 电磁兼容的PCB设计(一)
  8. oc实时渲染的图如何导出_如何高效学习C4D?看完这篇文章你就知道了!
  9. TIA安装GSD文件
  10. 机器学习---黑箱原理
  11. 电源电压测试肯定要电流探头吗?
  12. 深刻对比一下阿里云服务器和腾讯云服务器的优劣和区别
  13. 【python教程入门学习】拒绝反爬虫!教你搞定爬虫验证码
  14. @Deprecated 的功能
  15. nginx中报403 Forbidden问题
  16. mysql报错:1406, Data too long for column
  17. fbm是什么意思_fba是什么意思
  18. 最大似然估计(Maximum Likehood Estimation,MLE)和最大后验估计(Maximum A Posteriori estimation, MAP)
  19. BZOJ4833 [Lydsy1704月赛]最小公倍佩尔数
  20. 百度朱光:将技术基因注入百度金融,是我们未来三五年要做的事

热门文章

  1. mysql解压包安装出现 No such file or directory错误的解决办法
  2. C# 根据文本设置combobox的两种方法
  3. 【赠书活动】清华社的两本Android技术书籍
  4. python正则计算器(转)
  5. 如何编辑PDF文件,教你几招轻松搞定
  6. 初探 amaze-vue( 基于vue.js封装的Amaze UI 组件库)
  7. java:输出流程printStream
  8. Kafka 分区备份实战
  9. 移动Web利器transformjs入门
  10. Eclipse SVN修改用户名和密码