bzoj 1007 水平可见直线

本文介绍了一种通过构建下凸包解决直线可见性问题的方法。首先对直线的斜率进行排序,接着使用单调栈来维护下凸包。最终输出经过排序处理后的直线编号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

有一些直线若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的

思路:

可以看出来最后图形应该为一个下凸包

对于下凸包上的每个点,斜率都应该递增,而且横坐标递增

因此我们先对每条线的斜率进行排序

然后使用单调栈维护即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<set>
 8 #include<map>
 9 #include<vector>
10 #include<stack>
11 #include<queue>
12 #define ll long long
13 #define inf 2147383611
14 #define MAXN 50100
15 using namespace std;
16 inline ll read()
17 {
18     ll x=0,f=1;
19     char ch;ch=getchar();
20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 struct sline
25 {
26     double k,b;
27     int num;
28 }l[MAXN],st[MAXN];
29 const double eps=1e-8;
30 bool cmp1(sline A,sline B) {return A.k<B.k||(fabs(A.k-B.k)<eps&&A.b<B.b);}
31 bool cmp2(sline A,sline B) {return A.num<B.num;}
32 double insct(sline A,sline B)
33 {
34     return (B.b-A.b)/(A.k-B.k);
35 }
36 int n,top;
37 int main()
38 {
39     n=read();
40     for(int i=1;i<=n;i++) {scanf("%lf%lf",&l[i].k,&l[i].b);l[i].num=i;}
41     sort(l+1,l+n+1,cmp1);
42     for(int i=1;i<=n;i++)
43     {
44         while(fabs(st[top].k-l[i].k)<eps&&top) top--;
45         while(insct(st[top],st[top-1])>=insct(l[i],st[top-1])&&top>1) top--;
46         st[++top]=l[i];
47     }
48     sort(st+1,st+top+1,cmp2);
49     for(int i=1;i<=top;i++) printf("%d ",st[i].num);
50 }
View Code

转载于:https://www.cnblogs.com/yyc-jack-0920/p/7718394.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值