zoukankan      html  css  js  c++  java
  • [BZOJ 3707] 圈地

    Link:

    BZOJ 3707 传送门

    Solution:

    很不错的一道思维题

    可以发现枚举完两点后最优点就是最接近该直线的点

    如果将该直线看作$y$轴用两边$x$坐标的绝对值最小的点更新即可

    于是可以将所有斜率排序后不断旋转$y$轴并维护当前按$x$从小到大的序列

    发现对于直线$(x,y)$,两点$x$坐标的相对关系仅在$y$轴斜率超过直线斜率后才会变化

    因此每处理完一条直线,将两点的顺序交换即可!

    注意:这题BZOJ好像有锅,本身就垂直于$y$轴的直线必须最后处理

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    #define pb push_back
    typedef double db;
    typedef pair<db,db> P;
    typedef long long ll;
    const int MAXN=1e3+10;
    db res=1e60,INF=1e60;P dat[MAXN];
    int n,seq[MAXN],mp[MAXN],tot;
    
    P operator - (P a,P b)
    {return P(a.X-b.X,a.Y-b.Y);}
    inline db Cross(P a,P b)
    {return a.X*b.Y-a.Y*b.X;}
    inline db Slope(P a,P b)
    {return a.X!=b.X?(a.Y-b.Y)/(a.X-b.X):INF;}
    struct Line{double x,y,slope;}line[MAXN*MAXN];
    bool cmp(Line a,Line b){return a.slope<b.slope;}
    inline db solve(int a,int b,int c)
    {return fabs(Cross(dat[b]-dat[a],dat[c]-dat[a]))/2.0;}
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lf%lf",&dat[i].X,&dat[i].Y);
        sort(dat+1,dat+n+1);
        for(int i=1;i<=n;i++) 
            seq[i]=mp[i]=i;
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
        //注意与y轴平行的线要放在最后处理(数据的锅?)
                line[++tot]=(Line){i,j,Slope(dat[i],dat[j])};
        sort(line+1,line+tot+1,cmp);
        //将y轴不断旋转并维护当前从左向右的序列 
        for(int i=1;i<=tot;i++)
        {
            int a=line[i].x,b=line[i].y;
            if(seq[a]>seq[b]) swap(a,b);
            if(seq[a]>1) res=min(res,solve(a,b,mp[seq[a]-1]));
            if(seq[b]<n) res=min(res,solve(a,b,mp[seq[b]+1]));
            swap(seq[a],seq[b]);
            swap(mp[seq[a]],mp[seq[b]]);
        }
        printf("%.2lf",res);
        return 0;
    }
  • 相关阅读:
    Element ui表单验证结束后再次打开清空验证信息
    oracle 新建用户 给用户设定权限
    oracle时间问题
    ORACLE 创建作业JOB例子
    ORACLE SQL PLUSE 创建作业 执行作业
    VS发布,签名出错 试图加载该页时出错,路径的形式不合法。
    Oracle 系统权限
    PL/SQL Developer 8.0 创建 Oracle Jobs 的疑惑
    信息系统系项目管理考试技巧
    水晶报表分组统计中如何让字段值居中显示
  • 原文地址:https://www.cnblogs.com/newera/p/9718056.html
Copyright © 2011-2022 走看看