这一题很无语,其实思路很简单,就是判断在直线的左右两边,但是用两次for循环遍历会出现tle~~~~
后来想了很久,我把所有的点都放在第一和第二象限,然后排序,首先呢维护一下把x轴上面的点记住l下面的点记作r
然后求一个和,然后遍历每一个点
#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;
}
个图转一下就会发现第三和第四象限的点是不一样的然后维护,,,