zoukankan      html  css  js  c++  java
  • hdu 6127---Hard challenge(思维)

    题目链接

    Problem Description
    There are n points on the plane, and the ith points has a value vali, and its coordinate is (xi,yi). It is guaranteed that no two points have the same coordinate, and no two points makes the line which passes them also passes the origin point. For every two points, there is a segment connecting them, and the segment has a value which equals the product of the values of the two points. Now HazelFan want to draw a line throgh the origin point but not through any given points, and he define the score is the sum of the values of all segments that the line crosses. Please tell him the maximum score.
     
    Input
    The first line contains a positive integer T(1T5), denoting the number of test cases.
    For each test case:
    The first line contains a positive integer n(1n5×104).
    The next n lines, the ith line contains three integers xi,yi,vali(|xi|,|yi|109,1vali104).
     
    Output
    For each test case:
    A single line contains a nonnegative integer, denoting the answer.
     
    Sample Input
    2
    2
    1 1 1
    1 -1 1
    3
    1 1 1
    1 -1 10
    -1 0 100
     
    Sample Output
    1
    1100
     
     
    题意:有 n 个点,每个点有个权值,点与点之间可以连成线段,线段的权值就是两个端点的权值乘积。任意两个点与原点不可能在一条直线上,求一条直线穿过的线段的最大权值和?
     
    思路:我们可以想到,有一条过原点的直线,那么直线穿过的线段都是由直线两侧的点互相连线组成的线段,进一步发现线段的权值和就是两侧的点权值和的乘积。有了前面的简化,我们可以对所有的点按照斜率进行排序,从最小斜率的点开始遍历计算,每次以过当前点的原点的直线为直线,那么我们需要计算两侧点权值和的乘积,那么复杂度是O(n*n)。我们可以优化:第一次以O(n) 遍历计算直线两侧的权值和,那么紧接着的下一次的直线划分的上下两侧只有上次的那个点不同,所以只需要O(1)的考虑上次直线上的那么点是应该加入上侧还是下侧。 所以这部分的做法是O(n) 的,但因为斜率排序是O(n*logn)的,所以整体的复杂度是
    O(n*logn)的。
     
    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const LL N=5e4+5;
    const double INF=1e18;
    struct Node{
        LL x,y;
        LL v;
        double f;
    }a[N];
    
    void cal(Node& t)
    {
        LL x=t.x;
        LL y=t.y;
        if(x==0) t.f=INF;
        else{
            t.f=(double)y*1.0/(double)x;
        }
    }
    LL cmp(const Node s1,const Node s2)
    {
        return s1.f<s2.f;
    }
    bool check(Node a,Node b)
    {
        if(((a.x*b.y-a.y*b.x)*1.0/a.x)>=0.0)
            return true;
        return false;
    }
    
    int main()
    {
        LL T; cin>>T;
        while(T--)
        {
            LL n; scanf("%lld",&n);
            LL tot=0;
            for(LL i=1;i<=n;i++)
            {
                scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].v);
                tot+=a[i].v;
                cal(a[i]);
            }
            if(n==1) { puts("0"); continue; }
            sort(a+1,a+n+1,cmp);
            LL ans=0,tmp1=0,tmp2=0;
            tmp1=a[1].v;
            for(LL i=2;i<=n;i++)
            {
               if(!check(a[1],a[i]))
                tmp1+=a[i].v;
            }
           tmp2=tot-tmp1;
           ans=max(tmp1*tmp2,ans);
           if(a[1].x<0) tmp1-=a[1].v;
           for(LL i=2;i<=n;i++)
           {
               if(a[i].x>=0) tmp1+=a[i].v;
               tmp2=tot-tmp1;
               ans=max(tmp1*tmp2,ans);
               if(a[i].x<0) tmp1-=a[i].v;
           }
           printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    玩懂Log,打开Android大门(sundy深入浅出)之一
    ListView 中getView的原理+如何在ListView中放置多个item(android.widget.ListView)
    验证视图状态MAC失败问题正确的解决办法
    Coolite Extjs Store开发心得(转)
    Delphi进制转换
    得到Exitjs DataView中图片文件名
    C#文件常用操作
    Delphi中TList类应用
    代码优化的第一步是判定程序热点(转)
    Asp.net性能优化
  • 原文地址:https://www.cnblogs.com/chen9510/p/7367878.html
Copyright © 2011-2022 走看看