zoukankan      html  css  js  c++  java
  • HDU

    pro:给定N个二维平面的关键点,保证两点连线不经过原点。现在让你安排一条经过原点,但是不经过关键点的直线,使得两边的和的乘积最大。

    sol:由于连线不经过原点,所以我们极角排序即可。

    具体:因为我们的直线只需要180°,所以我们用atan(y/x)来排序,atan的范围是(-pi/2,pi/2); 而不是atan2。 这样的话,我们需要特殊处理y轴上的点。 由于没有两个同时在y轴上,所以我们可以把他看成y轴旁边的,这样不影响结果。   然后就是旋转这个直线,分成点在头部或者尾部来讨论加入还是移除。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    const double pi=acos(-1.0);
    struct point{
        ll x,y,val;
        double angle;
    }a[maxn];
    bool cmp(point w,point v){
        return w.angle<v.angle;
    }
    int main()
    {
        int T,N; ll ans; ll x,y;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&N);  ans=x=y=0;
            rep(i,1,N) {
               scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].val);
               if(a[i].x==0) a[i].angle=0.5*pi;
               else a[i].angle=atan(1.0*a[i].y/a[i].x);
            }
            sort(a+1,a+N+1,cmp);
            rep(i,1,N) if(a[i].x<0) x+=a[i].val; else y+=a[i].val;
            ans=x*y;
            rep(i,1,N){
                if(a[i].angle<=0){
                   if(a[i].y<0||(a[i].x>0&&a[i].y==0)) x+=a[i].val,y-=a[i].val;
                   else x-=a[i].val,y+=a[i].val;
                }
                else {
                   if(a[i].y>0) x+=a[i].val,y-=a[i].val;
                   else x-=a[i].val,y+=a[i].val;
                }
                ans=max(ans,x*y);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    JDK+MyEclipse+Tomcat配置
    常用数据类型占内存字节数
    连连看核心算法
    gnuplot画图
    socket服务器的搭建-Mac
    AlertController提示框
    block-循环引用
    OC基础(21)
    OC基础(20)
    OC基础(19)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10746387.html
Copyright © 2011-2022 走看看