hdu6127

  • 題目大意

    平面上有n個點,每個點有一個價值,每兩個點之間都有一條線段,定義線段的值爲兩個點價值的乘積,現在讓你找一條過原點的直線(直線不經過任何一個節點),將這條直線所經過的所有線段的值求和,問最大的和是多少.

  • 分析

    我們容易知道如果確定了直線的位置,那麼將直線兩邊的點分別求和再乘起來就是答案

    那麼現在只需要枚舉直線的位置即可,只有當直線掃過點的時候值纔會發生變化,所以我們離散化地取枚舉每個節點,在跨過節點的時候只需要O(1)的複雜度就能對答案進行更新。

  • 代碼

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
using namespace std;
#define  LL long long int
const double pi=4*atan(1.0);
const int  MAXN=50009;
int T;
int n;
LL sum_up,sum_down;
struct Node
{
    int x,y,v;
    double r;
    bool is_up;//1表示在x軸上面
}node[MAXN];
double Get_r(int x,int y)//給定一個點的座標,如果這個點在x軸上方,返回這個點和原點連線與軸正方向的夾角。如果這個點在x軸下方,返回這個點和原點連線與軸負方向的夾角
{
    if(x==0)return pi;
    if(y==0)return 0;
    if(x<0 && y>0)return pi-atan(-(double)y/(double)x);
    if(x>0 && y<0)return pi-atan(-(double)y/(double)x);
    return atan((double)y/(double)x);
}
bool Get_up(int x,int y)//判斷一個節點在x軸上方還是下方,在x軸上的點正方向歸爲下方,負方向歸爲上方
{
    if(y>0)return 1;
    else if(y<0)return 0;
    else
    {
        if(x<0)return 1;
        else return 0;
    }
}
bool cmp(Node a,Node b)
{
    return a.r < b.r;
}
void In()
{
    sum_up=sum_down=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
         scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].v);
         if(node[i].x==0 && node[i].y==0)node[i].v=0;
         node[i].r=Get_r(node[i].x,node[i].y);
         node[i].is_up=Get_up(node[i].x,node[i].y);
         if(node[i].is_up==1)sum_up+=node[i].v;
         else sum_down+=node[i].v;
    }
}
LL Work()
{
    LL ans=sum_up*sum_down;
    double cur_r=0;
    int i=1;
    while(node[i].r==0)i++;
    while(i<=n)
    {
        cur_r=node[i].r;
        while(node[i].r==cur_r)
        {
            if(node[i].is_up==1)
            {
                sum_up-=node[i].v;
                sum_down+=node[i].v;
            }
            else
            {
                sum_up+=node[i].v;
                sum_down-=node[i].v;
            }
            i++;
        }
        ans=max(ans,sum_down*sum_up);
    }
    return ans;
}
void Test()
{
    cout<<"sum_up="<<sum_up<<",sum_down="<<sum_down<<endl;
    for(int i=1;i<=n;i++)cout<<node[i].is_up<<" ";
    cout<<endl;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        In();
        //Test();
        sort(node+1,node+n+1,cmp);
        cout<<Work()<<endl;
    }
}
/*
2
2
1 1 1
1 -1 1
3
1 1 1
1 -1 10
-1 0 100

1
4
1 0 4
0 1 5
0 -1 3
-2 0 6

*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章