【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1007

【题意】

【题解】



这个人讲得很好

http://blog.csdn.net/outer_form/article/details/50623551

可以先看一下;

看完之后再看下面的;

根据上面的分析;

可以知道最后所求的线段围成的是一个凹的多边形;

可知相邻的两条边,

它们的交点的横坐标必然是递增的;



如下图;

在把直线按照斜率递增排序之后;

假设第i条直线是可见的;

那么设第i+1条直线(斜率变大了)与第i条直线的交点为A;

然后再设第i+2条直线与第i条直线的交点为B;

上图可以看出;

如果B的横坐标比A的横坐标小,那么i+1就是不可见的了;

相反,第i+2条直线是可见的了;



相反,如上图;

如果B的横坐标比A的横坐标大,

那么i,i+1,i+2就都是可见的了;

根据这个举例;

可以想见;

我们要维护相邻的边的交点的横坐标不下降;

即单调递增;

如果遇到直线i;

crossx(i,sta[top])<=crossx(sta[top],sta[top-1]);

则直接把sta[top]删掉;

因为它不可见了;

直到crossx(i,sta[top])<=crossx(sta[top],sta[top-1])不成立为止;

则在把i加入栈中;

让直线i和直线sta[top-1]相邻;

这样i和sta[top-1]之前的线就都是相邻的了(之前指的是队列的里面的线);

总之就是维护相邻的线的交点的横坐标不下降.

用单调队列搞就好.



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const double eps = 1e-8;
const int N = 5e4+100; struct node
{
double k,a;
int id;
}; node bian[N],sta[N],zhan[N];
int n,tn,top;
bool bo[N]; bool cmp(node a,node b)
{
if (fabs(a.k-b.k)<eps)
return a.a>b.a;
else
return a.k < b.k;
} /*
y1 = k1x+b1
y2 = b2x+b2
*/
double crossx(node a,node b)
{
double k1 = a.k,k2 = b.k,b1 = a.a,b2 = b.a;
return (b2-b1)/(k1-k2);
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);
rep1(i,1,n)
{
scanf("%lf%lf",&bian[i].k,&bian[i].a);
bian[i].id = i;
}
sort(bian+1,bian+1+n,cmp);
tn = n;
n = 1;
sta[1] = bian[1];
rep1(i,2,tn)
if (fabs(bian[i].k-bian[i-1].k)>eps)
sta[++n] = bian[i];
rep1(i,1,n)
{
while (top)
{
if (top>1 && crossx(sta[i],zhan[top-1])<=crossx(zhan[top],zhan[top-1]))
top--;
else
break;
}
zhan[++top] = sta[i];
}
rep1(i,1,top)
bo[zhan[i].id] = 1;
n = tn;
rep1(i,1,n)
if (bo[i])
printf("%d ",i);
return 0;
}

【BZOJ 1007】 [HNOI2008]水平可见直线的更多相关文章

  1. bzoj 1007 [HNOI2008]水平可见直线(单调栈)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5120  Solved: 1899[Submit][Sta ...

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

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4453  Solved: 1636[Submit][Sta ...

  3. 2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln, ...

  4. BZOJ 1007 [HNOI2008]水平可见直线 (栈)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7940  Solved: 3030[Submit][Sta ...

  5. BZOJ 1007: [HNOI2008]水平可见直线 栈/计算几何

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  6. BZOJ 1007: [HNOI2008]水平可见直线 平面直线

    1007: [HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则 ...

  7. bzoj 1007: [HNOI2008]水平可见直线 半平面交

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=1007; 题解 其实就是求每条直线的上半部分的交 所以做裸半平面交即可 #include ...

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

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

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

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

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

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

随机推荐

  1. ThinkPHP5.0---URL访问

    ThinkPHP 5.0 在没有启用路由的情况下典型的URL访问规则是(采用 PATH_INFO 访问地址): http://serverName/index.php(或者其它应用入口文件)/模块/控 ...

  2. Python 极简教程(六)运算符

    运算符,我们日常生活中使用的加减乘除,都是运算符的一种.当然这种一般我们称为算术运算符,用于处理数字运算的. 但是在计算机语言中,还有很多的运算符.用于处理不用的情况. 主要有以下几类: 算术运算符 ...

  3. Redis的高级应用-安全性和主从复制

    Redis的服务器命令和键值命令(String,Hash,List,Set,Zset)相对简单,只需查看文档即可. 文档地址: http://www.runoob.com/redis/redis-tu ...

  4. 【习题 6-9 UVA - 127】"Accordian" Patience

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 链表模拟即可. 1pile不能加s... [代码] #include <bits/stdc++.h> using nam ...

  5. 微信支付v2开发(2) 微信支付账号体系

    本文介绍微信支付账号体系各参数. 商户在微信公众平台提交申请资料以及银行账户资料,资料审核通过并签约后,可以获得表6-4所示帐户(包含财付通的相关支付资金账户),用于公众帐号支付. 帐号 作用 app ...

  6. angular 响应式表单(登录实例)

    一.表单验证 1. 只有一个验证规则: this.myGroup = this.fb.group({ email:['hurong.cen@qq.com',Validators.required], ...

  7. IOS获取preferreces偏好设置plistname名称的方法

    //获取preferreces偏好设置plistname名称的方法1 -(NSArray*)loadSpecifiersFromPlistName:(NSString*)plistName targe ...

  8. Android, IOS 史上最强多语言国际化,不仅第一次会尾随系统,并且会保存用户的语言设置

    劲爆消息,我提供源代码了.你能够先看完再下载.也能够先下载再看完, android源代码地址: https://github.com/hebiao6446/------Bluetooth-Androi ...

  9. bootstrap课程4 bootstrap的css样式有哪些内容需要注意

    bootstrap课程4 bootstrap的css样式有哪些内容需要注意 一.总结 一句话总结: 1.如何选择产品(框架)的版本? 大版本下的最后一个版本,但是同时又要选择稳定的版本,也就是如果做产 ...

  10. UVA 10047 - The Monocycle BFS

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...