【BZOJ】1007 水平可见直线
【分析】
维护一个下凸包。
首先依照斜率来从小到大排序。
考虑斜率同样的,肯定仅仅能选截距大的,把截距小的给筛掉。
然后用栈来维护下凸包。先压入前两条直线。
然后对于每一条直线i,设栈中上一条直线p=stk[stk[0]]和上上条直线q=stk[stk[0]-1]。
找到i与p的交点m。p与q的交点n。
画三条直线,把n点看成固定的,因为斜率从小到大,要使得上一条直线p看不到。那么m一定在n的左边,即m.x<=n.x。
假设看不到,就退栈,直到在右边。
最后输出,注意可能会存在n=1的情况。这个么,随便处理罢...
PS:网上的代码大多数都是错的,结果还能AC,这道题的数据非常水哟。
【代码】
<span style="font-size:18px;">#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std; const int N=50000;
const double eps=1e-5; struct Line
{
double k,b;
int id;
}line[N],_line[N];
struct Point
{
double x,y;
}now,last;
int n,_n,stk[N]; inline int dc(double i,double j)
{
if (fabs(i-j)<eps) return 0;
return i<j?-1:1;
} int cmp(Line La,Line Lb)
{
int r=dc(La.k,Lb.k);
return r?r<0:dc(La.b,Lb.b)>0;
} inline Point get_point(int i,int j)
{
double k1=_line[i].k,b1=_line[i].b,k2=_line[j].k,b2=_line[j].b; Point P;
P.x=(b2-b1)/(k1-k2);
P.y=(b1*k2-b2*k1)/(k1-k2);
return P;
} inline int cmp1(int i,int j)
{
return _line[i].id<_line[j].id;
} int main(void)
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lf%lf",&line[i].k,&line[i].b),line[i].id=i; sort(line+1,line+n+1,cmp);
for (int i=1;i<=n;i++)
{
if (_n&&!dc(line[i].k,_line[_n].k)) continue;
_line[++_n]=line[i];
} stk[++stk[0]]=1,stk[++stk[0]]=2;
for (int i=3;i<=_n;i++)
{
if (stk[0]&&!dc(_line[stk[stk[0]]].k,_line[i].k)) continue;
for (;stk[0]>=2;)
{
last=get_point(stk[stk[0]-1],stk[stk[0]]);
now=get_point(stk[stk[0]],i);
if (last.x>=now.x) stk[stk[0]--]=0; else break;
}
stk[++stk[0]]=i;
} sort(stk+1,stk+stk[0]+1,cmp1);
for (int i=1;i<=stk[0];i++)
{
if (!line[i].id) continue;
printf("%d ",_line[stk[i]].id);
}
printf("\n"); return 0;
}</span>
【BZOJ】1007 水平可见直线的更多相关文章
- BZOJ 1007 水平可见直线 | 计算几何
BZOJ 1007 水平可见直线 题面 平面直角坐标系上有一些直线,请求出在纵坐标无限大处能看到哪些直线. 题解 将所有直线按照斜率排序(平行的直线只保留最高的直线),维护一个栈,当当前直线与栈顶直线 ...
- BZOJ 1007 水平可见直线
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线: ...
- 【BZOJ】【1007】【HNOI2008】水平可见直线
计算几何初步 其实是维护一个类似下凸壳的东西?画图后发现其实斜率是单调递增的,交点的横坐标也是单调递增的,所以排序一下搞个单调栈来做就可以了…… 看了hzwer的做法…… /************* ...
- 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 ...
- 2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln, ...
- BZOJ 1007 [HNOI2008]水平可见直线 (栈)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7940 Solved: 3030[Submit][Sta ...
- BZOJ 1007: [HNOI2008]水平可见直线 栈/计算几何
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- BZOJ 1007: [HNOI2008]水平可见直线 平面直线
1007: [HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则 ...
随机推荐
- javascript前端下载
<html> <head> <title>测试标题</title> </head> <body> <div> 测试页 ...
- 【bzoj4408】[Fjoi 2016]神秘数 主席树
题目描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1+1+14 = 45 = 4+16 = 4+1+1 ...
- VIJOS 1889 天真的因数分解 ——莫比乌斯函数
同理BZOJ2440 二分答案,不过这次变成了统计含有平方因子的个数 #include <cmath> #include <cstdio> #include <cstri ...
- 【DFS求树的最大二分匹配+输入外挂】HDU 6178 Monkeys
http://acm.hdu.edu.cn/showproblem.php?pid=6178 [题意] 给定一棵有n个结点的树,现在有k个猴子分布在k个结点上,我们可以删去树上的一些边,使得k个猴子每 ...
- 【php wamp的配置】
- ubuntu问题解答集锦
一.su root提示认证失败 su root提示认证失败 ubuntu root是默认禁用了,不答应用root登陆,所以先要设置root密码. 执行:sudo passwd root 接着输入密 ...
- 洛谷 [P4151] 最大异或和路径
线性基 首先我们发现,对于一条路径走过去再走回来是没有意义的, 所以我们可以没有任何其他影响的取得一个环的异或和 所以我们预处理出来所有环的异或和,求出他们的线性基,然后任找一条 \(1 \sim n ...
- [其他] 关于C语言中使用未声明函数的问题
在c语言中,碰到一个.c文件,无.h头文件,在另一.c文件调用函数时,并没有进行声明extern, 此时编译器不会报错,会默认去查找同名的函数,这样会存在一些问题,查了些资料,稍微总结了下: 总结: ...
- 转 DOS 8.3 文件名命名规则
http://www.360doc.com/content/10/0813/14/73007_45757514.shtml DOS 8.3 文件名命名规则 经常看到命令行或者其它软件在显示目录的时候出 ...
- StoryBoard中使用xib
转自:http://blog.csdn.net/li6185377/article/details/8131042 一般自定义View 代码方式 有 在初始化的时候添加 子Vi ...