Language: C++

#include <iostream>
#include <stdlib.h>
#include <vector> //vector
#include <algorithm> //sort()
#include <numeric>
#include <tuple>
#include <cmath>
#include <queue>
#include <boost/multiprecision/cpp_int.hpp>

#define rep0(i, n) for(int i=0; i<(int)(n);i++)
#define rep1(i, n) for(int i=1; i<=(int)(n);i++)
#define all(x) (x).begin(), (x).end()
#define debug(a) if(flagdebug){cout << "debug (" #a "):" << endl << (a) << endl;}

using namespace std;
using bint = boost::multiprecision::cpp_int;
typedef uint64_t ulint;
typedef int64_t lint;

template<class T> inline bool chmin(T& a, T b);
template<class T> inline bool chmax(T& a, T b);
template<typename T> ostream& operator<<(ostream& s, const vector<T>& v);

template<class T> lint sum(vector<T> a);
template<class T> double ave(vector<T> a);


bool flagdebug = false;

struct result
{
    lint dx;
    lint dy;
    double dist;
    double deg;
};



int main(){
//////////////////////////////////////////////////////

    flagdebug = true; ///本番時削除！！！！！

    //入力

    lint n;
    cin >> n;

    vector<lint> x(n+1);
    vector<lint> y(n+1);
    vector<result> engines(n+1);
    rep1(j, n)
    {
        cin >> engines[j].dx;
        cin >> engines[j].dy;
    }

    //初期化
    //vector<result> dp(n+1);

    int div = 36;

    vector<result> dp(div);
    vector<vector<bool>> used(div, vector<bool>(n+1, false));
    rep0(k,div)
    {
        dp[k].dx = 0;
        dp[k].dy = 0;
        dp[k].dist = 0.0;
        dp[k].deg = 0.0;
    }
    rep1(i,n)//回目
    {
        rep1(j,n)//エンジン
        {
            rep0(k,div) //方角
            {
                if(used[k][j] == true)continue;
                result tmp;
                tmp.dx = dp[k].dx + engines[j].dx;
                tmp.dy = dp[k].dy + engines[j].dy;
                tmp.dist = sqrt((double)tmp.dx * (double)tmp.dx + (double)tmp.dy * (double)tmp.dy);
                tmp.deg = atan2(tmp.dy, tmp.dx);

                if(tmp.deg > (6.29/div * k) && tmp.deg < (6.29/div *(k+1)) )
                {
                    dp[k] = tmp;
                    used[k][j] = 1;
                }

                // switch(k)
                // {
                //     case 0:
                //         if(tmp.dx>=0 && tmp.dy>=0 && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 1:
                //         if(tmp.dx<=0 && tmp.dy>=0 && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 2:
                //         if(tmp.dx<=0 && tmp.dy<=0 && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 3:
                //         if(tmp.dx>=0 && tmp.dy<=0 && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;

                //     case 4: //x正でのみ評価
                //         if(tmp.dx > dp[k].dx)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 5:
                //         if(tmp.dy > dp[k].dy)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 6: 
                //         if(tmp.dx < dp[k].dx)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 7: 
                //         if(tmp.dy < dp[k].dy)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;

                //     case 8:
                //         if(tmp.dx>=0 && tmp.dy>=0 && tmp.dx * 2 < tmp.dy && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 9:
                //         if(tmp.dx<=0 && tmp.dy>=0 && tmp.dx * 2 < tmp.dy && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 10:
                //         if(tmp.dx<=0 && tmp.dy<=0 && tmp.dx * 2 < tmp.dy && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 11:
                //         if(tmp.dx>=0 && tmp.dy<=0 && tmp.dx * 2 < tmp.dy && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;

                //     case 12:
                //         if(tmp.dx>=0 && tmp.dy>=0 && tmp.dx < tmp.dy * 2 && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 13:
                //         if(tmp.dx<=0 && tmp.dy>=0 && tmp.dx < tmp.dy * 2  && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 14:
                //         if(tmp.dx<=0 && tmp.dy<=0 && tmp.dx < tmp.dy * 2  && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;
                //     case 15:
                //         if(tmp.dx>=0 && tmp.dy<=0 && tmp.dx < tmp.dy * 2  && tmp.dist > dp[k].dist)
                //         {
                //             dp[k] = tmp;
                //             used[k][j] = 1;
                //         }
                //         break;


                }
            }
            
        }
    }

    double ans = 0.0;

    rep0(k,div)
    {
        if(ans<dp[k].dist)ans = dp[k].dist;
    }

    cout << std::fixed;
    cout << std::setprecision(20) << ans << endl;





    //2次元配列
    //vector<vector<lint>> mat(row, vector<lint>(column, 初期値));
    //ペア
    //pair<lint,lint> p = make_pair(1,2);
    //vector<pair<lint,lint>> c(100010, pair<lint,lint>(0,0));
    //タプル
    //tuple<lint,lint,lint> t  = make_tuple(1,2,3);


    //昇順ソート
    //sort(all(a));
    //降順ソート
    //sort(all(a),greater<lint>());
    //特殊なソート（ラムダ式）
    //sort(all(mat), [&i](const vector<lint> &a, const vector<lint> &b){return a[i] < b[i];});
    // //[&i]は参照する変数，いらなければからの大括弧でよし．
    
    //////////////////////////////////////////////////////
    //キュー
    //queue<lint> que;
    //que.push(value);
    //que.front(); //先頭を参照
    //que.top(); //トップを参照（消されないので消したい場合は直後にpop()を使う）
    //que.pop(); //追い出す
    //que.empty(); //空なら1，あれば0
    //優先度付きキュー
    //priority_queue<lint> que;
    //キューにque.push()で入れると最大値順に並べられる．que.pop()で取り出すときは常に最大値が前にくる．
    //最小値から取り出したい時はpriority_queue< lint, std::vector<lint>, std::greater<lint> >
    //////////////////////////////////////////////////////
    //スタック
    //stack<lint> stk;
    //stk.push(value);
    //stk.top(); //先頭を参照（消されないので消したい場合は直後にpop()を使う）
    //stk.pop(); //トップを削除
    //stk.empty(); //空なら1,あれば0
    //stk.size(); //数
    //


   

    // sort(input.begin() , input.end());

    // uint64_t max = numeric_limits<uint64_t>::max();


    //////////////////////////////////////////////////////
    // DP

//     // 無限大の値
//     const uint64_t INF = (uint64_t)1 << 60;
//     //const int64_t NINF = -1 * ((int64_t)1 << 60 );
 
//     // DP テーブル
//     uint64_t dp[100010];

//     //DPテーブル初期化（最小化用）
//     for (int i = 0; i < 100010; ++i)
//     {
//         //dp[i] = INF;
//         dp[i] = 0;
//     } 

//     // 初期条件
//     dp[0] = 0;

//     // ループ
//     for (int i = 1; i <= n; ++i) {
//         //chmin( dp[i], dp[i - 1] + abs( input[i] - input[i - 1] ));
//         //if (i < 2)continue;
//         //chmin( dp[i], dp[i - 2] + abs( input[i] - input[i - 2] ));



//         // chmax ( dp [i] , dp[i - 1]);
//         // chmax ( dp [i] , dp[i - 1] + input[i]);
//         // cout << "dp[" << i <<"] = " << dp[i] << endl;

//     }



// //////////////////////////////////////////////////////

//     cout << dp[n] << endl;

//////////////////////////////////////////////////////
// Ctrl + Opt + N to make
    return 0;
}


struct node
{
    node* parent;
    node* firstchild;
    node* lastchild;
    node* olderbrother;
    node* youngerbrother;
    lint childnum;
    lint value;
public:
    node()
    {
        parent = NULL;
        firstchild = NULL;
        lastchild = NULL;
        olderbrother = NULL;
        youngerbrother = NULL;
        childnum = 0;
        value = 0;
    }

    void addchild(node* newchild)
    {
        if(childnum == 0)
        {
            firstchild = newchild;
        }
        else
        {
            lastchild->youngerbrother = newchild;
            newchild->olderbrother = lastchild;
            
        }
        lastchild = newchild;
        newchild->parent = this;
        childnum++;
    }
    void deletechild(node* child)
    {
        if(child->parent != this)return;
        if(child->youngerbrother != NULL)
        {
            child->youngerbrother->olderbrother = child->olderbrother;
        }
        if(child->olderbrother != NULL)
        {
            child->olderbrother->youngerbrother = child->youngerbrother;
        }
        childnum--;
    }

    bool operator<(const node &another) const{return value < another.value;};
    bool operator>(const node &another) const{return value > another.value;};   
};



// vectorprint用
template<typename T> ostream& operator<<(ostream& s, const vector<T>& v) {
	int len = v.size();
	for (int i = 0; i < len; ++i) {
		s << v[i]; if (i < len - 1) s << "\t";
	}
	return s;
}

// 最大公約数
ulint gcd(lint a, lint b){
    if(b!=0){gcd(b, a % b);}
    return a;    
}
ulint gcd(vector<lint> v){
    lint l = v.size();
    if(l>=2){
        v[l-2] = gcd(v[l-2] , v[l-1]);
        v.pop_back();
    }
    if(l==1)return v[0];
    else return 0;
}

//最小公倍数
ulint lcm(lint a, lint b){
    return a / gcd(a, b) * b;
}
ulint lcm(vector<lint> v){
    lint l = v.size();
    if(l>=2){
        v[l-2] = lcm(v[l-2], v[l-1]);
        v.pop_back();
    }
    if(l==1)return v[0];
    else{
        return 0;
    }
}

Compiler output:
a.cc:9:10: fatal error: boost/multiprecision/cpp_int.hpp: No such file or directory
    9 | #include <boost/multiprecision/cpp_int.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.