That's a problem from Polish Olympiad in Informatics, called Pionek (PIO).
Given a set of not unique vectors, find the greatest possible euclidean distance in reference to (0,0) point you can achieve by moving using vectors from the set. Every vector can be used only once. Return square of found distance.
For every vector
[x, y]
from set, we know that10^-4 <= x,y <= 10^4
For n, number of vectors in set, the inequality
n <= 200 000
is satisfiedMemory limit is
128MB
Example input:
5 -> number of vectors
2 -2 -> [x, y] vector
-2 -2
0 2
3 1
-3 1
We will achieve the best result by choosing vectors [0,2], [3,1], [2, -2]. Our final destination point will be (5, 1), so the square of euclidean distance from (0,0) to (5,1) is 26, and that's valid result for this input.
I wrote below brute force solution:
#include <iostream>
#include <vector>
using namespace std;
long long solve(const vector<pair<int, int>>& points, int i, int x, int y) {
if (i == points.size())
return 1LL * x * x + 1LL * y * y;
long long ans = 0;
ans = max(solve(points, i + 1, x, y), solve(points, i + 1, x + points[i].first, y + points[i].second));
return ans;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;
cin >> n;
vector<pair<int, int>> points(n);
for (int i = 0; i < n; ++i)
cin >> points[i].first >> points[i].second;
cout << solve(points, 0, 0, 0);
}
Of course, it's too slow (most of test cases require execution time below 0.5s or below 1.5s). I can use memoization, but then I exceed the memory limit.
Except above brute force, I have no idea what could I do. How can we solve it with acceptable time complexity, like O(nlogn)?