wxyww

一个OIER

我们要有最朴素的生活,与最遥远的梦想。即使明日天寒地冻,路远马亡。


AtCoder Beginner Contest 139F Engines

链接

problem

给出$n$个二元组$(x,y)$。最初位于原点$(0,0)$,每次可以从这$n$个二元组中挑出一个,然后将当前的坐标$(X,Y)$变为$(X+x,Y+y)$,每个二元组只能被选一次。选出一些二元组,使得按照这些二元组移动后与原点的欧几里得距离最大。求这个距离。

solution

将这$n$个二元组看做$n$个向量。移动方式遵循平行四边形定则。所以两个向量夹角越小,相加形成的和向量模长就越大。所以将这些向量按照极角排序。选择的向量肯定是一个区间。枚举左右端点,求最大值即可。

code

//@Author: wxyww
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
#include<cmath>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
#define pi pair<double,double>
const int N = 110;
ll read() {
	ll x = 0,f = 1; char c = getchar();
	while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9') {x = x * 10 + c - '0',c = getchar();}
	return x * f;
}
pi a[N];
bool cmp(const pi &A,const pi &B) {
	return atan2(A.second , A.first) < atan2(B.second , B.first);
}
int main() {
	int n = read();
	for(int i = 0;i < n;++i) a[i].first = read(),a[i].second = read();
	sort(a,a + n,cmp);
	double ans = 0;
	for(int i = 0;i < n;++i) {
		double X = a[i].first,Y = a[i].second;
		ans = max(ans,X * X + Y * Y);
		for(int j = (i + 1) % n;j != i;j = (j + 1) % n) {
			X += a[j].first,Y += a[j].second;
			ans = max(ans,X * X + Y * Y);
		}
	}
	printf("%.10lf",sqrt(ans));
	return 0;
}
最近的文章

cometOJ10C 鱼跃龙门

题目链接problem实际上就是对于给定的$n$求一个最小的$x$满足$\frac{x(x+1)}{2}=kn(k\in N^*)$。solution对上面的式子稍微变形可得$x(x+1)=2kn$。因为$x$与$(x+1)$互质,所以将$n$质因数分解后,同种质因子肯定都位于$x$或$(x+1)$中。$10^{12}$以内的整数质因数分解后种类不超过$13$种,所以可以暴力枚举每种质因子属于$x$还是$x+1$。然后分别得到$a$和$b$。下面要使得$bx=ay+1$。扩展欧几里得求解即...…

数学,质因数分解继续阅读
更早的文章

正睿暑期培训day1考试

链接A理解一下题意,然后玩几组样例就能发现,实际上就是$k$个$i$等价于$1$个$i-1$。所以就类似于$k$进制进行进位,如果最后$0$位上不是$0$,那么就存在划分方案。否则就不存在划分方案。输出第一次划分方案就记录一下每个数字是不是后面的数字凑出来的。如果是的话就像后面数字连边。这样就形成了一棵$k$叉树。最后$dfs$一遍输出即可。考场上$vector$下标从1开始记录了。就$wa$惨了。。。/** @Author: wxyww* @Date: 2019-08-04 11:41:...…

继续阅读