.真的要好好思考一下了,这种题根本就不难,或者说,不难在编码水平,而难在问题的转化,高中都学过积角排序qwq。
太菜qwq,给定一些点,他们两两之间都有一条线段,线段的权是他们之间的和。
然后再给你一条直线,如果这条直线经过这些线段,就加上他们的权
问 怎么摆放这条直线,他们的边权最大。
-。-把这些点 用一条直线分成两份,然后求他们的乘积和最大。
http://acm.hdu.edu.cn/showproblem.php?pid=6127
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
*/
const double PI=acos(-1.0);
const int maxn=5e4+1000;
struct Node{
double x,y;
double jd;
int v;
bool up;
}node[maxn];
bool cmp2(Node a,Node b){
return a.jd<b.jd;
}
int main()
{ int t;
int m;
scanf("%d",&t);
while(t--){
ll all_1=0;ll all_2=0;
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%lf%lf%d",&node[i].x,&node[i].y,&node[i].v);
if(!node[i].x) node[i].jd=PI/2.0;
else node[i].jd=atan(node[i].y/node[i].x);
if(node[i].x>=0) {node[i].up=true;all_1+=node[i].v;}
else {node[i].up=false;all_2+=node[i].v;}
}
//记录 积角
long long ans=1ll*all_1*all_2;
//cout<<ans<<endl;
sort(node,node+m,cmp2);
for(int i=0;i<m;i++){
if(node[i].up){
all_1-=node[i].v;
all_2+=node[i].v;
ans=max(ans,all_1*all_2);
}
else
{ all_1+=node[i].v;
all_2-=node[i].v;
ans=max(ans,all_1*all_2);
}
}
printf("%lld\n",ans);
}
return 0;
}