zoukankan      html  css  js  c++  java
  • 【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

    acm.hdu.edu.cn/showproblem.php?pid=6127

    【题意】

    • 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权
    • 这n个点两两可以连乘一条线段,定义每条线段的权值为线段两端点点权的乘积
    • 现在要过原点作一条直线,要求这条直线不经过任意一个给定的点
    • 在所有n个点两两连成的线段中,计算与这条直线有交点的线段的权值和
    • 最大化这个权值和并输出
    • 题目保证,给定的n个点不重合且任意两个点的连线不经过原点

    【思路】

    • 一条经过原点的直线把n个点分成两个半平面A,B
    • 假设A中的点权分别为a1,a2....an;B中的点权分别为b1,b2,......bm。则结果为sumA*sumB
    • 极角排序,枚举每个起点,线性扫一圈,计算半平面的点权之和,不断更新最优值

    【AC】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<algorithm>
     7 
     8 using namespace std;
     9 typedef long long ll;
    10 const int maxn=5e4+2;
    11 int n;
    12 double xx[maxn];
    13 double yy[maxn];
    14 ll val[maxn];
    15 ll ans[maxn];
    16 
    17 double dis(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
    18 const double eps = 1e-6;
    19 struct Point
    20 {
    21     double x;
    22     double y;
    23     ll val;
    24     double dis;
    25     double alf; 
    26     Point(){}
    27     Point(double _x,double _y):x(_x),y(_y){}
    28     Point(double _x,double _y,ll _val):x(_x),y(_y),val(_val){}
    29     Point operator -(const Point &t) const
    30     {
    31         return Point(x-t.x,y-t.y);
    32     }
    33     double operator ^(const Point &t)const
    34     {
    35         return (x*t.y)-(y*t.x);
    36     }
    37 }p[maxn];
    38 Point o(0.0,0.0);
    39 bool cmp(const Point &a, const Point &b)//先按象限排序,再按极角排序,再按远近排序 
    40 {
    41     if (a.y == 0 && b.y == 0 && a.x*b.x <= 0)return a.x>b.x;
    42     if (a.y == 0 && a.x >= 0 && b.y != 0)return true;
    43     if (b.y == 0 && b.x >= 0 && a.y != 0)return false;
    44     if (b.y*a.y <= 0)return a.y>b.y;
    45     return ((a-o)^(b-o))> 0.0 || (((a-o)^(b-o)) == 0.0 && a.x < b.x);    
    46 }
    47 
    48 int main()
    49 {
    50     int T;
    51     scanf("%d",&T);
    52     while(T--)
    53     {
    54         memset(ans,0,sizeof(ans));
    55         scanf("%d",&n);
    56         ll sum=0;
    57         for(int i=0;i<n;i++)
    58         {
    59             scanf("%lf%lf%I64d",&xx[i],&yy[i],&val[i]);
    60             p[i]=Point(xx[i],yy[i],val[i]);    
    61             sum+=val[i];
    62         }   
    63         sort(p,p+n,cmp); 
    64         int l=1;
    65         ll res;
    66         ans[0]+=p[0].val;
    67         for(int i=0;i<n;i++)
    68         {    
    69             if(i>0) ans[i]=ans[i-1]-p[i-1].val;
    70             while(((p[i]-o)^(p[l]-o))>0)
    71             {
    72                 ans[i]+=p[l].val;
    73                 l=(l+1)%n;     
    74             }   
    75             if(i==0) res=ans[i]*(sum-ans[i]);
    76             else res=max(res,ans[i]*(sum-ans[i]));
    77         }
    78         printf("%I64d
    ",res); 
    79     }
    80     return 0;
    81 }
    极角排序+线性扫模板

    【模板】

    1 bool cmp(const Point &a, const Point &b)//先按象限排序,再按极角排序,再按远近排序 
    2 {
    3     if (a.y == 0 && b.y == 0 && a.x*b.x <= 0)return a.x>b.x;
    4     if (a.y == 0 && a.x >= 0 && b.y != 0)return true;
    5     if (b.y == 0 && b.x >= 0 && a.y != 0)return false;
    6     if (b.y*a.y <= 0)return a.y>b.y;
    7     return ((a-o)^(b-o))> 0.0 || (((a-o)^(b-o)) == 0.0 && a.x < b.x);    
    8 }
    极角排序,o是中心点
     1    int l=1;
     2         ll res;
     3        // ans[0]+=p[0].val;
     4         for(int i=0;i<n;i++)
     5         {    
     6             //if(i>0) ans[i]=ans[i-1]-p[i-1].val;
     7             while(((p[i]-o)^(p[l]-o))>0)
     8             {
     9                // 必要的运算 
    10                 l=(l+1)%n;     
    11             }   
    12             //这里更新答案 
    13         }
    线性扫
  • 相关阅读:
    史上最全最新java面试题合集二(附答案)
    史上最全最新Java面试题合集一(附答案)
    修改vsftpd的默认根目录/var/ftp/pub到其他目录
    重置密码解决MySQL for Linux错误:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    虚拟机下的Linux连接校园网上网问题
    CentOS7 安装Chrome
    CentOS7 卸载Firefox
    100个写作高级词
    【二叉搜索树】的详细实现(C++)
    【红黑树】的详细实现(C++)
  • 原文地址:https://www.cnblogs.com/itcsl/p/7375608.html
Copyright © 2011-2022 走看看