这一题很无语,其实思路很简单,就是判断在直线的左右两边,但是用两次for循环遍历会出现tle~~~~
把第3象限的点对称到第一象限,第四象限的点对称到第2象限这样x轴在逆时针旋转的时候在第一象限碰到的点相当于在第1与第3象限碰到的点,
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=66666;
const double PI=acos(-1.0);
struct Point
{
double x,y;
int val;
double vec;
Point(){}
Point(double _x,double _y)
{
x=_x;
y=_y;
}
};
Point p[maxn];
bool cmp(Point a,Point b)
{
return a.vec<b.vec;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int m;
cin>>m;
ll l=0;
ll r=0;
for(int i=0;i<m;i++)
{
cin>>p[i].x>>p[i].y>>p[i].val;
if(p[i].y<0)
{
r+=p[i].val;
}
else
l+=p[i].val;
if(p[i].x<0&&p[i].y<0)
{
p[i].vec=atan2(-p[i].y,-p[i].x);
}
else if(p[i].x>0&&p[i].y<0)
{
p[i].vec=atan2(-p[i].y,-p[i].x);
}
else
p[i].vec=atan2(p[i].y,p[i].x);
}
sort(p,p+m,cmp);
/*for(int i=0;i<m;i++)
{
cout<<p[i].x<<" "<<p[i].y<<endl;
}*/
ll max1=l*r;
for(int i=0;i<m;i++)
{
if(p[i].x<0&&p[i].y<=0)
{
l+=p[i].val;
r-=p[i].val;
}
else if(p[i].x>0&&p[i].y<0)
{
l+=p[i].val;
r-=p[i].val;
}
else
{
l-=p[i].val;
r+=p[i].val;
}
max1=max(max1,l*r);
}
cout<<max1<<endl;
}
return 0;
}