给你n个向量,让你挑出一些使得总和的距离最大
1、考虑答案里面的向量一定是极角差在 pi以内的
2、(1)计较排序(2)双指针维护区间
3、在末尾也放一遍向量并且 ang+=2pi
每次pop也同样更新答案并且在放这个元素前更新答案:比较困惑
为什么这样对比较模糊
参考博客:https://www.cnblogs.com/asd123www/p/9596185.html 作者:GXZlegend
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<math.h>
#include <iostream>
#define en '\n'
typedef long long ll;
#define pa pair<ll, ll>
const ll mod = 10007;
const int maxn =4e5+10;
const ll inf = 1e15;
const double pi=acos(-1.0);
using namespace std;
template < class T > void rd( T &x)
{
x=0;T f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
struct node{
ll x,y;
double ang;
}a[maxn];
bool cmp(node a,node b){
return a.ang<b.ang;
}
bool ok(ll x,ll y){
if(a[y].ang-a[x].ang>=pi)return 1;
return 0;
}
signed main() {
#ifdef local
freopen("input2.txt", "r", stdin);
#endif
int n;
cin>>n;
for(ll i=1;i<=n;i++){
rd(a[i].x);rd(a[i].y);
a[i].ang=atan2(a[i].y,a[i].x);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
a[n+i]=a[i];
a[n+i].ang+=2*pi;
}
ll l=1;
ll x=0;
ll y=0;
ll ans=0;
for(ll r=1;r<=2*n;r++){
ans=max(ans,x*x+y*y);
while(l<r and ok(l,r)){
x-=a[l].x,y-=a[l].y;l+=1;
ans=max(ans,x*x+y*y);
}
x+=a[r].x,y+=a[r].y;
}
ans=max(ans,x*x+y*y);
cout<<ans<<en;
return 0;
}