首页 > 其他 > 详细

abc139_f

时间:2020-03-24 18:01:19      阅读:62      评论:0      收藏:0      [点我收藏+]

题目描述

给定 \(N\) 个向量,选出一些向量使得它们的和的模长最大。

正解

发现选出来的向量,在极角排序之后一定是一段连续的区间。

由于数据范围很小,我这里给出的是 \(O(n^2)\) 做法,但其实还有更加优秀的 \(O(n \log n)\),(复杂度瓶颈在排序上,找区间用 two-pointer )。

\(\color{DeepSkyBlue} {Code :}\)

#include <bits/stdc++.h>
#define N 105

using namespace std;

int n;

struct vec {
	long long x, y;
	vec (long long tx = 0, long long ty = 0) { x = tx, y = ty; }
	vec operator + (const vec &t) const { return vec(x + t.x, y + t.y); }
	vec operator - (const vec &t) const { return vec(x - t.x, y - t.y); }
	long long lenth() { return x * x + y * y; }
}a[2 * N];

bool cmp(const vec &lhs, const vec &rhs) {
	return atan2(lhs.y, lhs.x) < atan2(rhs.y, rhs.x);
}

inline int read() {
	int x = 0; bool neg = false; char ch = getchar();
	while(!isdigit(ch)) (ch == ‘-‘) && (neg = true), ch = getchar();
	while(isdigit(ch)) x = x * 10 + ch - ‘0‘, ch = getchar();
	return neg ? -x : x;
}

int main() {
	n = read();
	for(int i = 1; i <= n; ++i)
		a[i].x = read(), a[i].y = read();
	
	sort(a + 1, a + n + 1, cmp);
	
	for(int i = 1; i <= n; ++i)
		a[n + i] = a[i];
	
	vec cur;
	long long ans = 0;
	for(int l = 1; l <= n; ++l) {
		cur = vec(0, 0);
		for(int r = l; r < l + n; ++r) {
			cur = cur + a[r];
			ans = max(ans, cur.lenth());
		}
	}
	
	printf("%.10lf\n", sqrt(ans));
	return 0;
}

abc139_f

原文:https://www.cnblogs.com/Lskkkno1/p/12559701.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!