在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条直线两两不重合.求出所有可见的直线.
题目名称 | 1831. [HNOI 2008]水平可见直线 |
---|---|
输入输出 | bzoj_1007.in/out |
难度等级 | ★★★ |
时间限制 | 1000 ms (1 s) |
内存限制 | 128 MiB |
测试数据 | 10 |
题目来源 | Asm.Def 于2014-12-01加入 |
开放分组 | 全部用户 |
提交状态 | |
分类标签 | |
分享题解 |
通过:116, 提交:313, 通过率:37.06% | ||||
HZOI_蒟蒻一只 | 100 | 0.035 s | 0.99 MiB | C++ |
Asm.Def | 100 | 0.080 s | 1.51 MiB | C++ |
test | 100 | 0.082 s | 2.99 MiB | C++ |
HouJikan | 100 | 0.096 s | 0.89 MiB | C++ |
sxysxy | 100 | 0.097 s | 1.05 MiB | C++ |
Cydiater | 100 | 0.101 s | 30.83 MiB | C++ |
苜 | 100 | 0.102 s | 1.10 MiB | C++ |
FoolMike | 100 | 0.102 s | 1.63 MiB | C++ |
泪寒之雪 | 100 | 0.103 s | 1.46 MiB | C++ |
doriko | 100 | 0.104 s | 1.44 MiB | C++ |
关于 水平可见直线 的近10条评论(全部评论) | ||||
---|---|---|---|---|
必须对平行线的情况特殊判断。
当斜率最小的两条直线是平行线的时候,求出线的集合会存在平行线。 | ||||
#include<bits/stdc++.h>
#define RG register #define il inline #define N 50010 #define db double using namespace std; struct point{ db x,y; point() {} point(db _x,db _y):x(_x),y(_y) {} point operator + (const point & a)const{return point(x+a.x,y+a.y);} point operator - (const point & a)const{return point(x-a.x,y-a.y);} point operator * (const db k)const{return point (k*x,k*y);} db operator * (const point & a){return x*a.y-y*a.x;} }; struct line{ db k,b;int id; line() {} line(db K,db B,int I):k(K),b(B),id(I) {} }l[N]; int que[N]; bool comp(const line & a,const line & b){return a.k<b.k;} int n,ans[N]; bool check(line l1,line l2,line l0){ db k1=l1.k,b1=l1.b,k2=l2.k,b2=l2.b; db k3=l0.k,b3=l0.b;db kk,bb,kkk,bbb; if(k1-k2<0)kk=k2-k1,bb=b1-b2;else kk=k1-k2,bb=b2-b1; if(k3-k2<0)kkk=k2-k3,bbb=b3-b2;else kkk=k3-k2,bbb=b2-b3; return bb*kkk>bbb*kk; } int main(){ freopen("bzoj_1007.in","r",stdin); freopen("bzoj_1007.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i){ db k,b;scanf("%lf%lf",&k,&b); l[i]=line(k,b,i); }sort(l+1,l+n+1,comp);int top=2; que[1]=1,que[2]=2; for(int i=3;i<=n;++i){ while(top>=2&&check(l[que[top-1]],l[que[top]],l[i]))top--; que[++top]=i; }if(n==1)cout<<1<<" ",exit(0); for(int i=1;i<=top;++i)ans[++ans[0]]=l[que[i]].id; sort(ans+1,ans+ans[0]+1); for(int i=1;i<=ans[0];++i)printf("%d ",ans[i]); return 0; }
hee
2017-07-24 12:03
10楼
| ||||
手工化简一下式子,直接long long就行了,根本不存在精度问题啊……
| ||||
| ||||
| ||||
人神共愤的精度问题。。。。。。
| ||||
回复 @Asm.Def : 现在已经rank17了。
| ||||
。。为什么我每次退队之前都要判断是否队为空。。
不可能为空的啊。。。 | ||||
回复 @raywzy :
可这是湖南省选原题啊…
Asm.Def
2014-12-02 11:55
3楼
| ||||
此题和1634.赛车重了吧。。
raywzy
2014-12-02 08:45
2楼
|
在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条直线两两不重合.求出所有可见的直线.
第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格
3
-1 0
1 0
0 0
1 2