NC13328 倒水

题目

题目描述

有一个大水缸,里面水的温度为 \(T\) 单位,体积为 \(C\) 升。另有 \(n\) 杯水(假设每个杯子的容量是无限的),每杯水的温度为 \(t[i]\) 单位,体积为 \(c[i]\) 升。

现在要把大水缸的水倒入 \(n\) 杯水中,使得 \(n\) 杯水的温度相同,请问这可能吗?并求出可行的最高温度,保留 \(4\) 位小数。

注意:一杯温度为 \(t_1\) 单位、体积为 \(c_1\) 升的水与另一杯温度为 \(t_2\) 单位、体积为 \(c_2\)升的水混合后,温度变为 \(\frac {t_1c_1+t_2c_2}{c_1+c_2}\) ,体积变为 \(c_1+c_2\)

输入描述

第一行一个整数 \(n\) , \(1 ≤ n ≤ 10^5\)
第二行两个整数 \(T,C\) , 其中 \(0 ≤ T ≤ 10^4, 0 ≤ C ≤ 10^9\)
接下来 \(n\) 行每行两个整数 \(t[i],c[i]\)
\(0 < t[i], c[i] ≤ 10^4\)

输出描述

如果非法,输出“Impossible”(不带引号)否则第一行输出“Possible"(不带引号),第二行输出一个保留 \(4\) 位小数的实数表示答案。

样例解释:往第二杯水中倒 \(0.5\) 升水
往第三杯水中到 \(1\) 升水
三杯水的温度都变成了 \(20\)

示例1

输入

3
10 2
20 1
25 1
30 1

输出

Possible
20.0000

题解

知识点:贪心,数学。

要使温度都相同,假设所有体积 \(C\) 液体都用上,则有如下等式

\[\frac {t_1c_1+Tc_1'}{c_1+c_1'} = \cdots = \frac {t_nc_n+Tc_n'}{c_n+c_n'} = Ans = \frac {\sum_{i=1}^n t_ic_i + TC}{\sum_{i=1}^n c_i+C} \]

现在分三种情况:

  1. \(ans \leq \underset{1 \leq i \leq n}{min} \{t_i\}\) ,因为答案要取大的,根据函数连续性,至少一个点使得 \(ans = \underset{1 \leq i \leq n}{min} \{t_i\}\) ,因此温度最小值即是答案。
  2. \(ans \geq \underset{1 \leq i \leq n}{max} \{t_i\}\) ,此时 \(ans\) 可以直接作为答案。
  3. \(\underset{1 \leq i \leq n}{min} \{t_i\} < ans < \underset{1 \leq i \leq n}{max} \{t_i\}\) ,这种情况不可能。因为温度调整是趋向于 \(T\)\(t_i\) 之间的但不能达到两端点,如果要使两侧温度向中间靠拢,则必然 \(\underset{1 \leq i \leq n}{min} \{t_i\} < T < \underset{1 \leq i \leq n}{max} \{t_i\}\) ,若 \(T = ans\) ,则 \(T\) 作为控温端点是无法达到的,即 \(ans\) 无法达到;若 \(T\neq ans\) ,则必然有一部分 \(t_i\) 要跨越 \(T\) ,这也是不可能的。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    double T, C;
    cin >> T >> C;
    double maxt = 0, mint = 1e5;
    double sum1 = T * C, sum2 = C;///等比定理
    for (int i = 0;i < n;i++) {
        double t, c;
        cin >> t >> c;
        maxt = max(maxt, t);
        mint = min(mint, t);
        sum1 += t * c;
        sum2 += c;
    }
    double ans = sum1 / sum2;
    if (ans <= mint) cout << "Possible\n" << fixed << setprecision(4) << mint << '\n';
    else if (ans >= maxt) cout << "Possible\n" << fixed << setprecision(4) << ans << '\n';
    else cout << "Impossible\n";
    return 0;
}
posted @ 2022-06-15 20:43  空白菌  阅读(105)  评论(1)    收藏  举报