ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

在无限大的二维平面的原点(0,0)放置着一个棋子。你有n条可用的移动指令,每条指令可以用一个二维整数向量表
示。每条指令最多只能执行一次,但你可以随意更改它们的执行顺序。棋子可以重复经过同一个点,两条指令的方
向向量也可能相同。你的目标是让棋子最终离原点的欧几里得距离最远,请问这个最远距离是多少?

Input

第一行包含一个正整数n(n<=200000),表示指令条数。
接下来n行,每行两个整数x,y(|x|,|y|<=10000),表示你可以从(a,b)移动到(a+x,b+y)。

Output

输出一行一个整数,即最大距离的平方。
最大距离的向量,由所有在这个向量上投影为正的向量相加得到。扫描线扫一圈枚举这个方向,记录答案。
#include<bits/stdc++.h>
typedef long long i64;
const int N=2e5+7;
int _(){int x;scanf("%d",&x);return x;}
int n;
struct pos{
    int x,y;
    double a;
    bool operator<(const pos&w)const{return a<w.a;}
}ps[N*2];
const double pi=acos(-1);
int main(){
    n=_();
    for(int i=1;i<=n;++i){
        ps[i].x=_();
        ps[i].y=_();
        ps[i].a=atan2(ps[i].y,ps[i].x);
        if(!ps[i].x&&!ps[i].y)--i,--n;
    }
    std::sort(ps+1,ps+n+1);
    int sx=0,sy=0;
    i64 ans=0;
    for(int i=1,j=1;i<=n;++i){
        ps[n+i]=(pos){ps[i].x,ps[i].y,ps[i].a+pi*2};
        for(;j<n+i&&ps[j].a-ps[i].a<pi+1e-13;++j){
            sx+=ps[j].x;
            sy+=ps[j].y;
            i64 v=(i64)sx*sx+(i64)sy*sy;
            if(v>ans)ans=v;
        }
        sx-=ps[i].x;
        sy-=ps[i].y;
        i64 v=(i64)sx*sx+(i64)sy*sy;
        if(v>ans)ans=v;
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted on 2017-11-28 01:27  nul  阅读(610)  评论(0编辑  收藏  举报