hdu 6127-数学

来源:互联网 发布:金鼎智赢交易软件 编辑:程序博客网 时间:2024/06/05 18:38

题目链接:点击打开链接


题解思路:很简单,每次选取一个点,让原点与此点连接然后再使他偏离一点点,那么这个线就将点分为左右两边,ans就可以更新 ans = max(ans,v*max(l,r)+l*r);),v是此点的值,l,r分别表示两部分各自的和,先将点分为四个象限,各个象限按斜率从小到大排序,比如当枚举到第一象限时,两部分的其中一个部分应该是第二象限+此点在第一象限斜率递增部分的点+第三象限递减的部分,其他类似。


代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#define inf 0x3f3f3f3fusing namespace std;const int mx = 2e3+10;typedef long long ll;int n,m;ll to[4];struct node{    int x,y;    int v;    node(){}    node(int xx,int yy,int vv): x(xx),y(yy),v(vv){}    bool operator < (node A)const{        return 1.0*y/x < 1.0*A.y/A.x;    }}s1,s2;vector<node> vec[4];vector<ll>val[4];ll get_data(ll t,ll s,node no,int p,int p1){    int it = lower_bound(vec[p].begin(),vec[p].end(),no)-vec[p].begin();    int ip = lower_bound(vec[p1].begin(),vec[p1].end(),no)-vec[p1].begin();    ll l = (t + to[p] - val[p][it+1] + val[p1][ip]);    ll r = (s + val[p][it] + to[p1] - val[p1][ip]);    if(s1.y>0&&(p==0||p==3)) l += s1.v;    else if(s1.y<0||(p==1||p==2)) l += s1.v;    else r += s1.v;    if(s2.x>0&&(p==2||p==3)) r += s2.v;    else if(s2.x<0&&(p==0||p==1)) r += s2.v;    else l += s2.v;    return no.v*max(l,r)+l*r;}int main(){    int t;    scanf("%d",&t);    int a,b,c;    while(t--){        scanf("%d",&n);        for(int i=0;i<4;i++) vec[i].clear(),val[i].clear();        s1.v = s2.v = 0;        for(int i=1;i<=n;i++){            scanf("%d%d%d",&a,&b,&c);            if(a==0) s1 = node(a,b,c);            else if(b==0) s2 = node(a,b,c);            else if(a>0&&b>0) vec[0].push_back(node(a,b,c));            else if(a<0&&b>0) vec[1].push_back(node(a,b,c));            else if(a<0&&b<0) vec[2].push_back(node(a,b,c));            else vec[3].push_back(node(a,b,c));        }        for(int i=0;i<4;i++){            sort(vec[i].begin(),vec[i].end());            ll sum = 0;            val[i].push_back(0);            for(int j=0;j<vec[i].size();j++){                sum += vec[i][j].v;                val[i].push_back(sum);            }        }        ll ans = 0;        for(int i=0;i<4;i++) to[i] = val[i].back();        ll l = to[0]+to[3],r = to[1]+to[2];        if(s2.x>0) l += s2.v;        else r += s2.v;        ans = max(ans,s1.v*max(l,r)+l*r);        l = to[0]+to[1], r = to[2]+to[3];        if(s1.y>0) l += s1.v;        else r += s2.v;        ans = max(ans,s1.v*max(l,r)+l*r);        for(int i=0;i<vec[0].size();i++) ans = max(ans,get_data(to[1],to[3],vec[0][i],0,2));        for(int i=0;i<vec[1].size();i++) ans = max(ans,get_data(to[2],to[0],vec[1][i],1,3));        for(int i=0;i<vec[2].size();i++) ans = max(ans,get_data(to[3],to[1],vec[2][i],2,0));        for(int i=0;i<vec[3].size();i++) ans = max(ans,get_data(to[0],to[2],vec[3][i],3,1));        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击