1007: [HNOI2008]水平可见直线

题目:http://61.187.179.132/JudgeOnline/problem.php?id=1007

首先,将每条直线按斜率排序,斜率一样的可以把截距小的直线直接排除了(显然)。
接着,按排序后的顺序维护一个栈。
维护方法:求即将入栈的这条直线与栈顶直线求交点,若交点在栈顶直线与栈内第二条直线(从顶数起)交点的左侧,则栈顶直线退栈并再次执行此操作,直到交点在右侧,这条直线入栈。
最后,栈中剩下的直线就是能看见的直线。
#include <iostream>
#include 
<cstring>
#include 
<cstdio>
#include 
<cstdlib>
#include 
<algorithm>
#include 
<cmath>
using namespace std;
const int MaxN=50050;
const double oo=1000001;

struct line
{
    
double a,b;
    
int num;
}
;

int n;
line c[MaxN];
bool v[MaxN];
int st1[MaxN],top=0;
double st2[MaxN];

bool cmp(line a,line b)
{
    
if (a.a<b.a)
    
{
        
return 1;
    }

    
if (a.a>b.a)
    
{
        
return 0;
    }

    
return a.b>b.b;
}


double x(double x1,double y1,double x2,double y2)
{
    
return x1*y2-x2*y1;
}

    
//                 A                  B                    C                  D
double getjiao(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
    
double t=x(x2-x1,y2-y1,x3-x1,y3-y1)/x(x4-x1,y4-y1,x2-x1,y2-y1);
    
return x3+t*(x4-x3);
}


void work()
{
    st1[
0]=0;
    st2[
0]=oo;
    v[c[
0].num]=1;
    top
=0;
    
for (int i=1;i<n;i++)
    
{
        
if (c[i].a==c[i-1].a)
        
{
            
continue;
        }

        
while (1)
        
{
            
double k=getjiao(-oo,c[i].a*(-oo)+c[i].b,oo,c[i].a*oo+c[i].b,-oo,c[st1[top]].a*(-oo)+c[st1[top]].b,oo,c[st1[top]].a*oo+c[st1[top]].b);
            
if (k>st2[top] || top==0)
            
{
                top
++;
                st1[top]
=i;
                st2[top]
=k;
                v[c[i].num]
=1;
                
break;
            }

            
if (k<=st2[top])
            
{
                v[c[st1[top]].num]
=0;
                top
--;
            }

        }

    }

}


int main()
{
    cin
>>n;
    
for (int i=0;i<n;i++)
    
{
        cin
>>c[i].a>>c[i].b;
        c[i].num
=i;
        v[i]
=0;
    }

    sort(c,c
+n,cmp);
    work();
    
for (int i=0;i<n;i++)
    
{
        
if (v[i]==1)
        
{
            cout
<<i+1<<' ';
        }

    }

    cout
<<endl;
    
return 0;
}


posted on 2013-01-16 17:21 Kiro 阅读(342) 评论(0)  编辑 收藏 引用 所属分类: 衡八oj