# Mixing Water

## Problem Info

Mixing Water- Codeforces

## My Work

``````import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;

/**
* https://codeforces.com/problemset/problem/1359/C
* 3
* 30 10 20
* 41 15 30
* 18 13 18 should output 2, 7, and 1, each on a newline
*/
public final class WaterMix {
public static void main(String[] args) throws IOException {
for (int t = 0; t < testNum; t++) {
int hot = Integer.parseInt(info.nextToken());
int cold = Integer.parseInt(info.nextToken());
int target = Integer.parseInt(info.nextToken());
if (cold > hot) {
throw new IllegalArgumentException("invalid water temperatures lol");
}
double closest = Math.abs(hot - target);
int cupNum = 1;

double avg = (double) (hot + cold) / 2;
if (Math.abs(avg - target) < closest) {
cupNum = 2;
closest = Math.abs(avg - target);
}
if (avg < target) {
int theoretical = (cold - hot) / (hot + cold - 2 * target);
int loOdd = (theoretical - 1) / 2 * 2 + 1;
double loOddTemp = ((double) (loOdd - 1) * (hot + cold) / 2 + hot) / loOdd;
if (Math.abs(loOddTemp - target) < closest) {
closest = Math.abs(loOddTemp - target);
cupNum = loOdd;
}

int hiOdd = loOdd + 2;
double hiOddTemp =  ((double) (hiOdd - 1) * (hot + cold) / 2 + hot) / hiOdd;
if (Math.abs(hiOddTemp - target) < closest) {
cupNum = hiOdd;
}
System.out.println(loOddTemp + " " + hiOddTemp);
}
System.out.println(cupNum);
}
}
}
``````

It’s an O(T) solution using some math voodoo. The thing is, it fails for this test case, where for

``````1
999977 17 499998
``````

should output 499981, but my program outputs 499979.
However, I checked the average temperature for both, and they’re the same up to maximum precision.

How could I achieve greater precision?

Consider using my code for reference:

``````#include <bits/stdc++.h>
using namespace std;
double hot_water, cold_water, desired_temp;
/*
* This function checks whether pouring cupsPoured amount of cups achieves an average
* barrel temperature greater than or equal to desired_temp. Technically, this represents
* 2 * cupsPoured + 1 cups
*/
bool works (int cupsPoured) {
double totalBarrelTemperature = (hot_water * (cupsPoured + 1) + cold_water * (cupsPoured));
double totalCupsPoured = (double) (2 * cupsPoured + 1.0);
double avgBarrelTemperature = totalBarrelTemperature / totalCupsPoured;
return avgBarrelTemperature >= desired_temp;
}
void solve () {
/*
* maximumCups represents the the maximum number of cups such
* that the barrel temperature is greater than desired_temp.
*/
cin >> hot_water >> cold_water >> desired_temp;
// Binary search on the answer for maximumCups.
int left = 0, right = 1e6 + 1, maximumCups = 0;
while (left <= right) {
int mid = left + (right - left) / 2;
if (works(mid)) {
maximumCups = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
// If it is impossible to find a temperature close to desired_temp, then print 2
if (maximumCups == 1e6 + 1) {
cout << 2 << endl;
} else {
/*
* The solution must lie between barrel1 and barrel2 if the total number of cups
* is odd. barrel1 represents the barrel with an average temperature slightly
* greater than desired_temp. barrel2 represent the barrel with an average
* temperature slightly less than desired_temp. These two barrels will be the
* closest to desired_temp.
*/
double totalBarrel1 = (hot_water * (maximumCups + 1) + cold_water * (maximumCups));
double totalBarrel2 = (hot_water * (maximumCups + 2) + cold_water * (maximumCups + 1));
double barrel1Cups = (double)(2 * maximumCups + 1.0);
double barrel2Cups = (double)(2 * maximumCups + 3.0);
double avgBarrel1 = (totalBarrel1) / barrel1Cups;
double avgBarrel2 = (totalBarrel2) / barrel2Cups;
double hot_cold_avg = (hot_water + cold_water) / 2.0;
double minAbsDifference = min(abs(desired_temp - avgBarrel1),
min(abs(desired_temp - avgBarrel2),
abs(desired_temp - hot_cold_avg)));

/*
* If the minimum absolute difference from desired_temp is
* hot_cold_avg, then it suffices to print 2. Otherwise, print
* the barrel with the minimum absolute difference from desired_temp.
*/
if (minAbsDifference == abs(desired_temp - hot_cold_avg)) {
cout << 2 << endl;
} else if (minAbsDifference == abs(desired_temp - avgBarrel1)) {
cout << 2 * maximumCups + 1 << endl;
} else {
cout << 2 * maximumCups + 3 << endl;
}
}
}
int main() {
int t; cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
``````