CF126A

发布时间 2023-11-15 19:33:19作者: To_Carpe_Diem

Hot Bath 题解

题目简述

\(5\) 个正整数 \(t_{1}\)\(t_{2}\)\(x_{1}\)\(x_{2}\),$ t_{0} $。

这是一个简单的数学推理题。我们需要找到两个龙头的流速 \(y_1\)\(y_2\),使得满足以下条件:

  1. 最终水温不低于 \(t_0\)

  2. 在满足上一条的前提下,水温尽可能接近 \(t_0\)

  3. 在满足上一条的前提下,总流速尽可能大。

思路实现

根据题目描述,我们可以得出以下结论:

  • 如果 \(t_1 \geq t_0\),那么只需打开冷水龙头即可,此时 \(y_1\) 取最大值 \(x_1\)\(y_2\) 取 0。

  • 如果 \(t_2 \leq t_0\),那么只需打开热水龙头即可,此时 \(y_1\) 取 0,\(y_2\) 取最大值 \(x_2\)

接下来我们考虑 \(t_1 < t_0 < t_2\) 的情况。我们可以将问题分成两个子问题

  1. 打开冷水龙头,关闭热水龙头:此时只需调节冷水龙头的流速 \(y_1\)。根据公式 \(\dfrac{t_1\times y_1}{y_1} = t_1\),我们可以得到此时的水温。如果水温小于 \(t_0\),则继续减小 \(y_1\) 的值;如果水温大于等于 \(t_0\),则记录下此时的流速和水温差

  2. 打开热水龙头,关闭冷水龙头:此时只需调节热水龙头的流速 \(y_2\)。根据公式 \(\dfrac{t_2\times y_2}{y_2} = t_2\),我们可以得到此时的水温。如果水温大于 \(t_0\),则继续增大 \(y_2\) 的值;如果水温小于等于 \(t_0\),则记录下此时的流速和水温差

最后,我们从两个子问题中找到水温差最小的情况即可。

Code:

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
    long long t1, t2, x1, x2, t0;
    cin >> t1 >> t2 >> x1 >> x2 >> t0;

    double minDiff = 1e9; // 记录水温差的最小值
    pair<int, int> ans; // 记录结果

    // 子问题一:打开冷水龙头,关闭热水龙头
    for (int y1 = x1; y1 >= 0; y1--) {
        double temp = t1 * y1 / (double)y1; // 计算水温
        if (temp < t0) {
            break; // 水温小于 t0,继续减小 y1 的值
        }
        if (temp - t0 < minDiff) {
            minDiff = temp - t0;
            ans = make_pair(y1, 0);
        }
    }

    // 子问题二:打开热水龙头,关闭冷水龙头
    for (int y2 = x2; y2 >= 0; y2--) {
        double temp = t2 * y2 / (double)y2; // 计算水温
        if (temp >= t0) {
            break; // 水温大于等于 t0,继续增大 y2 的值
        }
        if (t0 - temp < minDiff) {
            minDiff = t0 - temp;
            ans = make_pair(0, y2);
        }
    }

    cout << ans.first << " " << ans.second << endl;

    return 0;
}

该解法的时间复杂度为 \(O(x_1 + x_2)\),即龙头的最大流速和。