题目:点击打开链接
题意:给出n个点,每个点有自己的权值,两点之间的连线的权值就是两个点的乘积,然后找到经过原点的一条直线,是其能通过的线的值最大,输出这能通过的最大值,
题解:先进行极角排序,然后逆时针加减计算,
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const double PI=acos(-1);
typedef long long ll;
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
else
{
if(x>0)
return 1;
else
return -1;
}
}
struct node
{
double theta;
double x,y,val;
bool operator<(const node& rhs) const
{
return theta<rhs.theta;
}
}p[50005];//极角排序
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",&p[i].x,&p[i].y,&p[i].val);
if(p[i].x==0)
p[i].theta=PI/2;
else
p[i].theta=atan(p[i].y/p[i].x);
}
sort(p+1,p+1+n);
ll sumr=0,suml=0;
for(int i =1;i<=n;i++)
{
if(dcmp(p[i].x)>=0)
sumr+=p[i].val;
else
suml+=p[i].val;
}
ll ans=suml*sumr;
for(int i=1;i<=n;i++)
{
if(p[i].x>=0)
{
sumr-=p[i].val;
suml+=p[i].val;
}
else
{
sumr+=p[i].val;
suml-=p[i].val;
}
ans=max(ans,sumr*suml);
}
printf("%lld\n",ans);
}
return 0;
}
本文介绍了一道算法题目,需要找出一条经过原点的直线,使得该直线上所有点的乘积最大。通过使用极角排序和计算策略来解决这个问题。
287

被折叠的 条评论
为什么被折叠?



