2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)
1007: [HNOI2008]水平可见直线
Time Limit: 1 Sec Memory Limit: 162 MB
Description
在xoy直角坐标平面上有n条直线L1,L2,…Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.
例如,对于直线:L1:y=x; L2:y=-x; L3:y=0则L1和L2是可见的,L3是被覆盖的.
给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.
Input
第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi
Output
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格
Sample Input
3
-1 0
1 0
0 0
Sample Output
1 2
这又是一道基础的计算几何,我简单说说我的思路吧。
如果我们把所有的线段按照他们的k" role="presentation" style="position: relative;">kk排序,相当于就是按照极角排序,冷静分析一下,显然排序过后的第一条直线和最后一条直线一定可以看到,然后再发散一下思维,如果我们将直线的方向固定,让斜率为负数的直线的箭头朝下,斜率为正数的直线箭头朝上,然后搞半平面交,在搞半平面交的同时如果有直线被弹出,那这根直线显然不能计入答案(请各位务必想清楚原因),最后for" role="presentation" style="position: relative;">forfor循环判一下标记就没了。
小技巧:这个时候我们只关心直线的位置关系,所以没有必要做纯种的半平面交,只需转化为点与点之间的关系就可以了,具体细节见代码吧。
代码如下:
#include<bits/stdc++.h>
#define N 50005
#define eps 1e-8
using namespace std;
struct line{
double x,y;
int id;
inline bool operator<(const line&a)const{return x==a.x?y>a.y:x<a.x;}
}l[N];
int n,head=0,q[N];
bool vis[N];
inline double calc(int i,int j){return (l[i].y-l[j].y)/(l[j].x-l[i].x);}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%lf%lf",&l[i].x,&l[i].y),l[i].id=i;
sort(l+1,l+n+1);
q[++head]=1;
for(int i=1;i<=n;++i){
if(l[i].x-l[i-1].x<eps)continue;
while(head>1&&calc(i,q[head])<=calc(q[head],q[head-1]))--head;
q[++head]=i;
}
for(int i=1;i<=head;++i)vis[l[q[i]].id]=1;
for(int i=1;i<=n;++i)if(vis[i])printf("%d ",i);
return 0;
}
2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)的更多相关文章
- BZOJ 1007: [HNOI2008]水平可见直线 栈/计算几何
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- bzoj 1007 [HNOI2008]水平可见直线(单调栈)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5120 Solved: 1899[Submit][Sta ...
- BZOJ 1007 [HNOI2008]水平可见直线
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4453 Solved: 1636[Submit][Sta ...
- BZOJ 1007 [HNOI2008]水平可见直线 (栈)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7940 Solved: 3030[Submit][Sta ...
- BZOJ 1007: [HNOI2008]水平可见直线 平面直线
1007: [HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则 ...
- bzoj 1007: [HNOI2008]水平可见直线 半平面交
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=1007; 题解 其实就是求每条直线的上半部分的交 所以做裸半平面交即可 #include ...
- bzoj 1007 : [HNOI2008]水平可见直线 计算几何
题目链接 给出n条直线, 问从y轴上方向下看, 能看到哪些直线, 输出这些直线的编号. 首先我们按斜率排序, 然后依次加入一个栈里面, 如果刚加入的直线, 和之前的那条直线斜率相等, 那么显然之前的会 ...
- BZOJ.1007.[HNOI2008]水平可见直线(凸壳 单调栈)
题目链接 可以看出我们是要维护一个下凸壳. 先对斜率从小到大排序.斜率最大.最小的直线是一定会保留的,因为这是凸壳最边上的两段. 维护一个单调栈,栈中为当前可见直线(按照斜率排序). 当加入一条直线l ...
- BZOJ 1007 [HNOI2008]水平可见直线 ——半平面交 凸包
发现需要求一个下凸的半平面上有几个交点. 然后我们把它变成凸包的问题. 好写.好调.还没有精度误差. #include <map> #include <ctime> #incl ...
随机推荐
- as3 加载库声音报错
排除法:(依次排序,从简单到难) 1.引用的声音类名与声音链接名字是否一致,可trace声音对象字符串检验 2.引用的声音对象是否不存在 ,可trace声音对象检验 3.最后检验是否当前swf中,其中 ...
- UI5-文档-4.33-Routing Back and History
现在我们可以导航到细节页面并显示发票,但是还不能回到概览页面.我们将向细节页面添加一个back按钮,并实现一个函数,再次显示概述页面. Preview A back button is now dis ...
- win10 ubuntu双系统安装后无法引导进入ubuntu
之前按照先装windows后装ubuntu的方式装的系统,都可以引导到ubuntu,无论是将ubuntu挂在到/boot在windows用easy BCD建立ubuntu引导,还是将ubuntu挂在到 ...
- centos7 jenkins 安装
前提: 安装了 jdk ,我的是jdk8 第一步: https://jenkins.io/download/ 下载 可以下载 rpm文件, 标红处, 也可以下载war包(Generic Java pa ...
- tomcat APR的配置
Tomcat 可以使用 APR 来提供超强的可伸缩性和性能,更好地集成本地服务器技术. APR(Apache Portable Runtime) 是一个高可移植库,它是 Apache HTTP Ser ...
- r.js打包
久闻r.js的大名,但实际没有用它做过任何东西.今天用它时,发现网上许多教程都不对.研究一下,把我的实际经验分享给大家. 例子1 先是HTML页面 <!DOCTYPE html> < ...
- VNC连接黑屏的问题
今天尝试在CentOS上安装一个VNC Server.CentOS5 已经自带了VNC,默认也已经安装了,只要配置一下就可以了(如果没有安装,可以:yum install vnc vncserver安 ...
- c pointer
1. 定义数组后,数组名是一个常数, 而指针是一个变量 如下: int a[10]; int *p; p=a; \\ 与 p=&a[0]等价 则*p++表示 a[1] 而 a++ 则是错误的 ...
- RNA-seq 安装 fastaqc,tophat,cuffilnks,hisat2
------------------------------------------ 安装fastqc------------------------------------------------- ...
- 64位windows+32位JDK8+32位eclipse是可以的