题目链接:HDU6127
题目大意:给你n个点,坐标X,Y,权值val,要求用一条过原点的直线将这些点分成左右两部分,任意两点的权值等于两点的权值乘积,问最大可划分出来的权值为?
题目思路:将所有点按照斜率排序,然后扫一圈即可,说着可能有点抽象,动手画一下图就明白了。每条直线左右点的权值=左边点权值和*右边点权值和。
代码参考:大佬的 代码
AC代码:
/*
HDU6127
2017年8月16日09:59:39
极角排序,暴力求解
AC
*/
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#define PI (acos(-1.0))
using namespace std;
typedef long long ll;
const int maxn=5e4+50;
const double eps=1e-8;
int dcmp(double x){
if(fabs(x)<eps) return 0;
return x>0 ? 1 : -1;
}
struct node{
int x,y,val;
double theta;
bool operator <(const node& b)const{
return theta<b.theta;
}
}a[maxn];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
//scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].val);
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].val);
if(a[i].x==0) a[i].theta=PI/2.0;//在Y轴上的点
else a[i].theta=atan(1.0*a[i].y/(1.0*a[i].x));
}
sort(a+1,a+1+n);
ll rsum=0,lsum=0;
for(int i=1;i<=n;i++){
if(a[i].x>0) rsum+=a[i].val;
else lsum+=a[i].val;
}
ll ans=lsum*rsum;
for(int i=1;i<=n;i++){
if(a[i].x>=0){
lsum+=a[i].val;
rsum-=a[i].val;
}
else{
lsum-=a[i].val;
rsum+=a[i].val;
}
ans=max(ans,lsum*rsum);
}
printf("%lld\n",ans);
}
return 0;
}