题意及官方题解:
补充:
我是以到x负半轴的弧度进行排序,然后扫过(0~PI)的弧度,中间每扫过一个点都要可能更新答案
代码:
#include<bits/stdc++.h>
const double pi=acos(-1.0);
using namespace std;
class point
{
public:
int x,y,v;
double radiu;
public:
point(){};
point (int a,int b)
{
x=a;
y=b;
}
}p[100010];
bool cmp(point a,point b){
return a.radiu<b.radiu;
}
double calc(int x,int y){
if (x<0 && y>0) return atan((double)1.0*y/((double)-1.0*x));
else if (x==0 && y>0)return (double)2.0*pi/4.0;
else if (x>0 && y>0) return (double)2.0*pi/4.0+atan((double)1.0*x/((double)1.0*y));
else if (x>0 && y==0)return (double)2.0*pi/2.0;
else if (x>0 && y<0) return (double)2.0*pi/2.0+atan((double)(-1.0*y)/(double)(1.0*x));
else if (x==0 && y<0)return (double)2.0*pi*((double)3.0/4.0);
else if (x<0 && y<0) return (double)2.0*pi*((double)3.0/4.0)+atan(((double)-1.0*x)/((double)-1.0*y));
else if (x<0 && y==0)return (double)0;
}
int main()
{
//freopen("1008.in","r",stdin);
//freopen("my_1008.out","w",stdout);
int T,n;
scanf("%d",&T);
while (T--)
{
long long sum = 0 , ss = 0 , ans = 0;
scanf("%d",&n);
for (int i=0 ; i<n ; i++)
{
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
p[i].radiu=calc(p[i].x,p[i].y);
sum += p[i].v;
}sort(p,p+n,cmp) ;
int s = 0 ,e = 0 ;
while(s<n&&p[s].radiu<=pi){
double ed = pi + p[s].radiu;
while(e<n&&p[e].radiu<=ed){
ss += p[e++].v ;
ans = max(ans,ss*(sum-ss));
}ss -= p[s++].v;
ans = max(ans,ss*(sum-ss));
}printf("%lld\n",ans);
}
return 0;
}