• [武汉加油] bzoj 5099: [POI2018]Pionek 几何+双指针


    几何+双指针

    题目大意:现在有 (n) 个向量,请你选出来一些向量使它们的和的长度最大,输出最大值的平方。

    假如我们已经知道了最终向量的方向,我们要想使长度最大,就需要将所有投影在最终向量正方向上的向量都加起来。

    所以我们可以按角度枚举最终向量的方向,我们需要加起来的就是一段移动的区间,我们可以用双指针来维护加起来的向量。

    因为最终向量的方向有可能是给出的向量,也有可能是向量之间间隔的方向,所以每次移动指针的时候都要更新一下答案.

    因为开始给出的向量不一定有序,所以我们需要先将向量排序。

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define LL long long
    using namespace std;
    int n;
    const double PI = acos(-1);
    LL sx, sy, ans;
    struct data
    {
    	LL x, y; double ang;
    	friend bool operator <(const data & a,const data & b) {return a.ang < b.ang;}
    }a[400010];
    int main()
    {
    	cin >> n;
    	for(int i = 1; i <= n; ++ i)scanf("%lld%lld", &a[i].x, &a[i].y), a[i].ang = atan2(a[i].y,a[i].x);
    	sort(a + 1, a + 1 + n);
    	for(int i = 1; i <= n; ++ i)a[n + i].x = a[i].x, a[n + i].y = a[i].y, a[n + i].ang = a[i].ang + 2 * PI;
    	for(int l = 1, r = 1; l <= n; ++ l)
    	{
    		while(r < n + l && a[r].ang - a[l].ang < PI)sx += a[r].x, sy += a[r].y, ans = max(ans, sx * sx + sy * sy), ++ r;
    		sx -= a[l].x, sy -= a[l].y, ans = max(ans, sx * sx + sy * sy);
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    nodejs cheerio模块提取html页面内容
    简短的perl程序
    laravel 模型操作
    Laravel 学习笔记
    记录一下应该养成的好习惯
    phpstudy设置允许远程访问mysql数据库
    删除专家账号,要注意删干净
    使用 Composer 安装Laravel扩展包的几种方法
    上传文件太大,后台无法获取到文件的问题
    在Laravel中使用mongoDB
  • 原文地址:https://www.cnblogs.com/wljss/p/12344129.html
Copyright © 2020-2023  润新知