您的位置:首页 > 大数据 > 人工智能

2017 Multi-University Training Contest - Team 7 Hard challenge

2017-08-23 11:31 489 查看
http://acm.hdu.edu.cn/showproblem.php?pid=6127

题意:

  给你n个点的坐标,每个点有一个val值,两两之间有一条连线,这条线的价值为两个点的val值的乘积,保证不会有连线穿过原点。现在有一条经过原点的直线,要你求穿过的线价值总和的最大值。

思路:

  直接进行极角排个序,然后进行扫描,从水平,然后旋转180度,每次把直线两边的点分成两部分,把值加起来相乘,就可以计算出一个最大值,因为题目说了任意直线不是经过原点的,每次碰到的肯定是一个点,而不是多个点。

代码:

#include<bits/stdc++.h>
#define maxn 50005
#define ll long long
using namespace std;
const double PI = acos(-1.0);
struct node{
ll x,y,val;
double ang;
}a[maxn];
bool cmp(node x,node y){
return x.ang < y.ang;
}
int main(){
ll m,n,T;
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
for(ll i = 1;i <= n;i++){
scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].val);
if(a[i].x){
a[i].ang = atan(1.0 * a[i].y / a[i].x);
}else{
a[i].ang = PI / 2;
}
}
ll l,r;
l = r = 0;
sort(a + 1,a + 1 + n,cmp);
for(ll i = 1;i <= n;i++){
if(a[i].x >= 0){
r += a[i].val;
}else{
l += a[i].val;
}
}
ll ans = l * r;
for(ll i = 1;i < n;i++){
if(a[i].x >= 0){
r -= a[i].val;
l += a[i].val;
}else{
r += a[i].val;
l -= a[i].val;
}
if(ans < l * r){
ans = l * r;
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐