在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条直线两两不重合.求出所有可见的直线.
标签:
半凸包。完全不会。。膜了黄学长的题解。。。高大上 啊。。。开始的时候const int eps=1e-8 WA了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) const int nmax=50005; const double eps=1e-8; struct edge{ double a,b;int num; }; edge edges[nmax]; bool cmp(edge x,edge y){ if(fabs(x.a-y.a)<eps) return x.b<y.b; return x.a<y.a; } double crossx(edge x,edge y){ return (y.b-x.b)/(x.a-y.a); } edge s[nmax]; int ans[nmax]; int main(){ int n;scanf("%d",&n); rep(i,n) scanf("%lf%lf",&edges[i].a,&edges[i].b),edges[i].num=i; sort(edges+1,edges+n+1,cmp); //rep(i,n) printf("%lf ",edges[i].a); int top=0; rep(i,n) { edge o=edges[i]; while(top){ if(fabs(s[top].a-o.a)<eps) top--; else if(top>1&&crossx(o,s[top-1])<=crossx(s[top],s[top-1])) top--; else break; } s[++top]=o; } rep(i,top) ans[s[i].num]=1; rep(i,n) if(ans[i]) printf("%d ",i); return 0; }
在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
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5672417.html