Looks like applying a physics problem today. Launching a probe. It's a pretty basic scenario in Game Design, as it applies a few concepts like iterating, velocities, changing velocities due to factors such as gravity, etc.
The hard part is the iteration. I can't think of a good way to try and 'hone in' on an optimal solution, so all I can think of is to go through every iteration in some sweeping way until there's no more chances of it going....
Hmm...
Actually, X and Y velocities are independent. So I can START by figuring out which X velocities are valid. That's going to be a much more restrictive set, as if X is too low it'll never reach the target, and if it's too high it will overshoot it. There will be some intermediate steps that may miss before they all overshoot immediately, so I'll just focus on finding the valid X-velocities first.
// Calculate valid X velocities; namely, velocities which for at least one
// value, will be in the target range. Fails if it stops moving without entering
// the target area;
vector<int> xVs;
for (int i = 0; i <= xmax; i++) {
int v = i, pos = 0;
while (v != 0) {
pos += v--;
if (pos >= xmin && pos <= xmax) { xVs.push_back(i); break; }
}
}
Sample input only has 21 valid X velocities, out of an initial 30. Cool!
Maybe if I try for Y as well? Though I don't actually know what the limit for it is... I can keep finding arbitrarily higher velocities. Plus, for each X-velocity, there's going to be a limited range of valid Y velocities. Right?
OH! I remember now! I need to find the Nyquist Frequency! Basically, the upper limit of Y is going to be when the velocity becomes greater than twice the depth of the target! Great! It's rather constrained, but even if it was pretty significatnly sized, I still think I'll be able to handle it pretty quickly.
... except no, that's not right. That's to prevent aliasing.
Whatever, I'm just going to choose an arbitrary value. Say 500. If I start getting wrong answers I'll try and be more clever;
// Calculate valid velocities
vector<pair<int, pair<int, int>>> coords;
for (auto x: xVs)
for (int y = 0; y < 500; y++) {
int highest = 0, v = y, pos = 0;
while (v >= ymin) {
pos += v--;
highest = max(highest, pos);
if (pos >= ymin && pos <= ymax) {
coords.push_back(pair<int, pair<int, int>>(highest, pair<int, int>(x, y)));
break;
}
}
}
pair<int, pair<int, int>> highest = coords[0];
for (auto c: coords)
if (c.first > highest.first)
highest = c;
Huh. First try. It ran pretty instantly too!
Oh awesome! This one is asking for every velocity that will eventually reach the target. Something which I'm already calculating for!
Even better... my solution already prints out how many valid pairs will reach it. I literally don't have to make any changes for this.
... nope, that's not it.
Ugh, I realized a bug... I'm never checking if the X-velocities are valid as well! Whelp.
// Calculate valid velocities
vector<pair<int, int>> coords;
for (auto x: xVs)
for (int y = -500; y < 500; y++) {
int highest = 0, vx = x, vy = y, xpos = 0, ypos = 0;
while (vy >= ymin) {
ypos += vy--;
xpos += vx;
vx = max(vx-1, 0);
if (ypos >= ymin && ypos <= ymax && xpos >= xmin && xpos <= xmax) {
coords.push_back(pair<int, int>(x, y));
break;
}
}
}
Yep, that works much better.
I just got kinda lucky that I got the answer for the first part.