TCO 2017, Round 1B, 250-Pointer (WaterAndOxygen)

James S. Plank

Mon Apr 10 22:10:03 EDT 2017
I'm afraid that I find this problem boring. It's algebra, plain and simple.

Now that you know it's algebra, give it a try. If you want more hints or you get stuck, see below.



















































Let's give some simple variable names to these quantities: The number of days that you can live, given the amount of water that you have left after converting A units to oxygen is:

(W - A) / Y

And the number of days that you can live, given the amount of oxygen that you have left after converting A units to oxygen is:

(X + A/2) / Z

To maximize the number of days that you live, set these equal to each other, and then solve for A. You have to check for impossibility:

Once you have A, convert it back to the number of days that you will live, but do it for both water and oxygen, in case the values differ, and take the minimum. Done.

My Solution

This one is straightforward - do the algebra, check the boundary conditions, done. The file is Solution.cpp.

/* Topcoder TCO 2017 Q1B 250-Pointer
 * James S. Plank
 * Mon Apr 10 22:27:22 EDT 2017
 */

#include <string>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

class WaterAndOxygen {
  public:
    double maxDays(int remainH20, int remainO2, int costH2O, int costO2);
};

double WaterAndOxygen::maxDays(int remainH20, int remainO2, int costH2O, int costO2)
{
  double Y, W, X, Z, B, A, Days_W, Days_O;

  W = remainH20;
  X = remainO2;
  Y = costH2O;
  Z = costO2;

  /* Do the algebra to calculate A which makes the 
     number of days that you live on water equal 
     the number of days you live on oxygen. */

  B = W / Y - X / Z;
  A = B * ( 2.0 * Z * Y ) / ( Y + 2.0 * Z );
  
  /* Make A legal. */

  if (A > W) A = W;
  if (A < 0) A = 0;

  /* Now, from A, calculate the number of days you live on water,
     and the number of days you live on oxygen, and return the minimum. */

  Days_W = (W - A) / Y;
  Days_O = (X + A/2.0) / Z;
  return (Days_O < Days_W) ? Days_O : Days_W;
}