zoukankan      html  css  js  c++  java
  • bzoj 1007 计算几何,单调栈

    1007: [HNOI2008]水平可见直线

    tags:在纸上画画还是很容易看出的,可以看到的部分是一个半凸包,且随着交点横坐标增大时,直线斜率增加。所以这题只要按斜率排好序,再维护一个单调栈即可。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    typedef long long ll;
    const int N = 5e4+10;
    
    struct Line{ int id; double a, b;
        friend bool operator < (const Line &a, const Line &b) {
            if(fabs(a.a-b.a)<eps) return a.b>b.b;
            return a.a<b.a;
        }
    }line[N];
    int n, top, Stack[N<<2], ans[N];
    double solve(int i, int j)
    {
        return (line[i].b-line[j].b)/(line[j].a-line[i].a);
    }
    int main()
    {
        scanf("%d", &n);
        rep(i,1,n) {
            scanf("%lf %lf", &line[i].a, &line[i].b);
            line[i].id=i;
        }
        sort(line+1, line+1+n);
        rep(i,1,n) if((i>1 && fabs(line[i].a-line[i-1].a)>eps) || i==1) {
            while(true) {
                if(top<=1) { Stack[top++]=i; break; }
                int nd=Stack[top-2], st=Stack[top-1];
                double x1=solve(nd, st), x2=solve(st, i);
                if(x2<=x1) top--;
                else { Stack[top++]=i; break; }
            }
        }
        rep(i,0,top-1) ans[line[Stack[i]].id]=1;
        rep(i,1,n) if(ans[i]) printf("%d ", i);
    
        return 0;
    }
  • 相关阅读:
    C#防止窗口重复打开
    c#image与byte数组的转换
    物理网卡地址
    C#[WinForm]实现自动更新
    js计算散点图方程式
    js遮罩效果
    js实现四舍六入 奇进偶舍
    ajax加载表格数据
    C#创建和调用WebService详细教程
    .NET中的CTS、CLS和CLR
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6493355.html
Copyright © 2011-2022 走看看