【栈】bzoj 1007 水平可见直线

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1007
题目大意:某个坐标系上有一坨直线,每根直线都表示为kx+b的形式,如果在任意时刻直线i位于最上方,则直线i是可见的,求所有可见直线的编号

这个居然是考试题,惊了
乱搞做法:
开始完全没有任何想法……但是会发现:任意两条k不同的直线都会有一个交点,于是我就脑洞出了做法……首先按k从小到大排序,k相同的留下b最大的一条即可,然后开始暴力找……
找到第一条,然后从它后面的找出一条和它相交最早的一条直线,如果有多条直线在同一时刻和它相交,只留那条k最大的,然后再把找到的这条直线作为开始的直线,再次向后暴力找(前面的不用管了),重复刚才的做法……直至找不到一条可以超过它的直线为止
时间复杂度O(n^2-出题人的良心) bzoj可AC233333
代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define INF 2147483647
using namespace std;
struct man
{
    int k,b,s;
}a[200000];
int ans[200000];

bool cmp(man x,man y)
{
    if(x.k != y.k)
        return x.k < y.k;
    return x.b < y.b;
}

int main()
{
    int n,cnt = 0,maxn = 0;
    scanf("%d",&n);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d%d",&a[i].k,&a[i].b);
        a[i].s = i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i = 1;i ;i )
    {
        while(a[i+1].k == a[i].k)
            i ++;
        ans[++cnt] = a[i].s;
        int k = 0;
        double fast = INF;
        for(int j = i+1;j <= n;j ++)
        {
            double time = (double)(a[j].b - a[i].b)/(a[i].k - a[j].k);
            if(time <= fast)
            {
                fast = time;
                k = j;
            }
        }
        i = k;
    }
    sort(ans+1,ans+cnt+1);
    for(int i = 1;i <= cnt;i ++)
        cout << ans[i] << " ";
    return 0;
}

正确做法:按k从小到大排序,开一个栈,如果下一条直线与top-1的交点横坐标小于与top交点的横坐标,那么就直接删除top,最后栈中的就是答案
代码?不要随便伸手要代码,自己能打出来不是更好吗?再说这题又不是很难(明明是你自己懒打好吗)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值