Editorial for La tina de Karel


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: leosangue

La temperatura actual de la bañera es:

\[ \frac{100X}{X+Y} \]

Si agregamos A cubetas calientes y B cubetas frías, la temperatura pasa a ser:

\[ \frac{100(X+A)}{X+Y+A+B} \]

Queremos encontrar A y B tales que:

\[ 100(X+A)=T(X+Y+A+B) \]

¿Cómo encontrar A y B?

Podemos construir la respuesta poco a poco.

En cada momento comparamos:

\[ 100(X+A) \]

con:

\[ T(X+Y+A+B) \]

Hay tres posibilidades:

  • Si son iguales, encontramos la temperatura exacta.
  • Si el lado izquierdo es mayor, significa que la mezcla está demasiado caliente. Agregamos una cubeta fría:

    \[ B++ \]

  • Si el lado izquierdo es menor, significa que la mezcla está demasiado fría. Agregamos una cubeta caliente:

    \[ A++ \]

Esto se repite hasta obtener exactamente la temperatura T.

Casos especiales

Para T = 100, no puede existir ninguna cubeta fría.

Por eso:

  • Si Y > 0 → IMPOSSIBLE.
  • Si ya existe agua caliente (X > 0) → 0 0.
  • Si X = Y = 0, necesitamos agregar una cubeta caliente → 1 0.

Para T = 0 ocurre lo contrario:

  • Si X > 0 → IMPOSSIBLE.
  • Si ya existe agua fría (Y > 0) → 0 0.
  • Si X = Y = 0, necesitamos agregar una cubeta fría → 0 1.

Para 0 < T < 100, el procedimiento iterativo encuentra la primera combinación que alcanza exactamente la temperatura, por lo que obtiene el mínimo número de cubetas agregadas.

Ejemplo

Para:

X = 3
Y = 5
T = 78

Inicialmente:

\[ 100(3)=300 \]

y:

\[ 78(3+5)=624 \]

La mezcla está demasiado fría, así que agregamos agua caliente.

Después de varias iteraciones llegamos a:

\[ A=36,\qquad B=6 \]

Entonces tenemos:

\[ X+A=39 \]

y:

\[ Y+B=11 \]

La temperatura es:

\[ 100\frac{39}{39+11}=100\frac{39}{50}=78 \]

Por lo tanto:

36 6

Complejidad

El ciclo va agregando una cubeta en cada iteración.

En el peor caso, el número de iteraciones depende de la cantidad de cubetas necesarias, pero con los límites dados es suficientemente pequeño.

  • Tiempo: O(A+B)
  • Memoria: O(1)

Código en C++

#include <bits/stdc++.h>
using namespace std;

void solve() {
    long long x, y, t;
    cin >> x >> y >> t;

    long long a = 0, b = 0;

    // Queremos obtener exactamente 100 grados.
    if (t == 100) {
        if (y > 0) {
            cout << "IMPOSSIBLE\n";
            return;
        }

        if (x > 0) {
            cout << "0 0\n";
            return;
        }

        // No hay agua. Necesitamos agregar una cubeta caliente.
        cout << "1 0\n";
        return;
    }

    // Queremos obtener exactamente 0 grados.
    if (t == 0) {
        if (x > 0) {
            cout << "IMPOSSIBLE\n";
            return;
        }

        if (y > 0) {
            cout << "0 0\n";
            return;
        }

        // No hay agua. Necesitamos agregar una cubeta fría.
        cout << "0 1\n";
        return;
    }

    // 0 < t < 100
    while (100 * (x + a) != (x + y + a + b) * t) {

        // La mezcla está demasiado caliente.
        if (100 * (x + a) > (x + y + a + b) * t) {
            b++;
        }
        // La mezcla está demasiado fría.
        else {
            a++;
        }
    }

    cout << a << ' ' << b << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while (T--) {
        solve();
    }

    return 0;
}
Idea clave

La comparación

\[ 100(X+A)\quad\text{vs.}\quad T(X+Y+A+B) \]

nos dice directamente hacia qué lado tenemos que mover la temperatura:

demasiado caliente → agregar agua fría
demasiado fría     → agregar agua caliente
exactamente T      → terminar

Así, el código no necesita despejar ninguna ecuación ni utilizar double; todo se mantiene con enteros, evitando errores de precisión.


Comments

There are no comments at the moment.