bzoj1007:[HNOI2008]水平可见直线

思路:首先按斜率排序,如果斜率相同就取截距最大的,显然截距小的会被覆盖而对答案没有贡献,然后考虑斜率不同的如何统计答案,可以用一个单调栈维护,当前新插入的直线显然斜率是要比当前栈顶斜率要大的,然后如果新插入的直线l[i]与stack[top]的交点在stack[top]与stack[top-1]的交点的右边,那么就不需要退栈直接加进来就好了,否则就要退栈直到条件成立。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 50005
#define eps 1e-7
 
int n,cnt,top,stack[maxn];
 
struct line{
    double k,b;
    int id;
    bool operator <(const line &a)const{return k<a.k ||(fabs(k-a.k)<eps && b<a.b);}
}l[maxn];
 
bool cmp(int a,int b){return l[a].id<l[b].id;}
 
double getpoint_x(line a,line b){
    return (b.b-a.b)/(a.k-b.k);
}
 
bool check(line a,line b,line c){
    return getpoint_x(a,b)>=getpoint_x(b,c);
}
 
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%lf%lf",&l[i].k,&l[i].b),l[i].id=i;
    sort(l+1,l+n+1);
    for (int i=1;i<=n;i++){
        while (fabs(l[i].k-l[i+1].k)<eps) i++;
        while (top>=2 && check(l[stack[top-1]],l[stack[top]],l[i])) top--;
        stack[++top]=i;
    }
    sort(stack+1,stack+top+1,cmp);
    for (int i=1;i<=top;i++) printf("%d ",l[stack[i]].id);
    return 0;
}

 

转载于:https://www.cnblogs.com/DUXT/p/6006943.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值