题目

在平面直角坐标系上以\(y=kx+b\)的形式给出\(n (n\le 50000)\)条直线,求从无限高的地方能看到多少条直线。

分析

举几个例子发现我们要求的直线组成一个下凸的形状。所以我们只要找出直线围成的下凸包即可。

对直线排序,\(k\)从小到大,\(b\)从大到小,用一个栈维护一下。如果当前元素与栈顶元素的交点在栈顶元素与栈中第二个元素的交点的左边,那么弹出栈顶(模拟一下就知道了)。

代码

计算几何尽量避免除法,因为会有精度问题,一般移项转化成乘法计算。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=5e4+10;
struct line {
double k,b;
int id;
bool operator < (const line a) const {
return k==a.k?b>a.b:k<a.k;
}
} a[maxn],sta[maxn];
int top=0;
bool bid(line a,line b) {
return a.id<b.id;
}
bool ans[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
int n;
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%lf%lf",&a[i].k,&a[i].b),a[i].id=i;
sort(a+1,a+n+1);
for (int i=1;i<=n;++i) {
while (top>1) if ((a[i].b-sta[top].b)*(sta[top-1].k-sta[top].k)<=(sta[top].b-sta[top-1].b)*(sta[top].k-a[i].k)) --top; else break;
sta[++top]=a[i];
}
for (int i=1;i<=top;++i) ans[sta[i].id]=true;
for (int i=1;i<maxn;++i) if (ans[i]) printf("%d ",i);
puts("");
}

最新文章

  1. memcached 的简介、安装、命令
  2. 模拟赛1030d2
  3. ios图标和默认图像
  4. Maven学习小结(三 基本概念)
  5. ARM学习笔记7——乘法指令
  6. SqlBulkCopy的一个例子
  7. VLC播放器架构剖析
  8. MySQL多Text字段报8126错误(解决过程)
  9. docker搭建私服
  10. GDB调试指南-启动调试
  11. 对strom的理解
  12. 以Attribute加上Header验证
  13. Ue4管线中的灯光信息
  14. Struts2第三天
  15. ora-24550 signo=6 signo=11解决
  16. [UnityShader基础]01.渲染队列
  17. bzoj千题计划228:bzoj2095: [Poi2010]Bridges
  18. UINavigationItem 设置UIBarButtonItem
  19. 绘制pathway富集散点图
  20. Shell脚本编写规范

热门文章

  1. 20155327 嵌入式C语言课堂补交
  2. Linux Shell中的特殊符号和含义简明总结(包含了绝大部份)
  3. Java——基于java自身包实现消息系统间的通信(TCP/IP+BIO)
  4. 使用iChecker的注意事项
  5. bzoj4998 星球联盟
  6. Unity CombineTexture
  7. Windows下遍历某目录下的文件
  8. redis 为什么快
  9. 技本功丨利用 Atomic 构建 React 项目工作流,so easy!
  10. Ubuntu16.04使用Tarball安装ntp