【loj6161】「美团 CodeM 初赛 Round A」倒水

来源:互联网 发布:淘宝聚划算入口 编辑:程序博客网 时间:2024/06/05 11:43

题目描述
有一个大水缸,里面的水温度为 TTT 单位,体积为 CCC 升。另有 nnn 杯水,每杯水有温度 tit_it
​i
​​ 单位与体积 cic_ic
​i
​​ 升。现在要把大水缸的水倒入 nnn 杯水中使得 nnn 杯水的温度相同,请问这是否可能?如果可能,请求出可行的最高的温度,保留 4 位小数。

注意:一杯温度为 t1t_1t
​1
​​ 单位,体积为 c1c_1c
​1
​​ 升的水与另一杯温度为 t2t_2t
​2
​​ 单位,体积为 c2c_2c
​2
​​ 升的水混合后温度变为 t1×c1+t2×c2c1+c2\frac{t_1\times c_1+t_2\times c_2}{c_1+c_2}
​c
​1
​​ +c
​2
​​

​t
​1
​​ ×c
​1
​​ +t
​2
​​ ×c
​2
​​
​​ ,体积变为 c1+c2c_1+c_2c
​1
​​ +c
​2
​​ 。
输入格式
第一行一个整数 nnn。 第二行两个整数 T,CT,CT,C。 接下来 nnn 行每行两个整数 ti,cit_i,c_it
​i
​​ ,c
​i
​​ 。
输出格式
如果非法,输出 Impossible。 否则第一行输出 Possible,第二行输出一个保留 4 位小数的实数表示答案。
样例
样例输入

3
10 2
20 1
25 1
30 1
样例输出

Possible
20.0000
样例解释

往第二杯水中倒 0.50.50.5 升水。 往第三杯水中到 111 升水。 三杯水的温度都变成了 202020。
数据范围与提示
1≤n≤105,0≤ti,ci,T≤104,0≤C≤1091\le n\le 10^5,0\le t_i,c_i,T\le 10^4,0\le C\le 10^91≤n≤10
​5
​​ ,0≤t
​i
​​ ,c
​i
​​ ,T≤10
​4
​​ ,0≤C≤10
​9
​​ 。

题解
转自 http://blog.csdn.net/a1799342217/article/details/76448190

分三种情况讨论。
1.max(a[i])>t>min(a[i]) 直接输出Impossible。因为不论怎么加水,温度只会无限趋近于t而达不到t,n杯水的温度不可能相等。
2.min(a[i])>=t 此时加水只会让温度降低,因此只有温度为min(a[i])时才能相等,计算所有水温度降至min(a[i])所需的水的量,然后与c比较。若大于c则为Impossible,否则最大温度为min(a[i])。
3.max(a[i])<=t 此时加水会让温度升高,先计算所有水温度到达max(a[i])所需的水的量,若c仍有剩余,就把剩下的都加进去,计算最后的温度即为答案。

代码

#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 100000using namespace std;int t,n,ma,mi=0x7fffffff;double c;int a[MAXN+5],b[MAXN+5];int main(){    scanf("%d",&n);    scanf("%d%lf",&t,&c);    int now=c,ss=0;    for (int i=1;i<=n;i++){        scanf("%d%d",&a[i],&b[i]);        ss+=b[i]; ma=max(ma,a[i]); mi=min(mi,a[i]);    }    if (mi<t&&ma>t){        printf("Impossible\n");        return 0;    }    if (mi>=t){        bool flag=false;        for (int i=1;i<=n;i++){            double x;            if (mi!=t) x=(double)(a[i]-mi)*b[i]/(mi-t);            c-=x;            if (c<-0.001||(mi==t&&a[i]>mi)){                flag=true;                break;            }        }        if (flag){            printf("Impossible\n");            return 0;        }        else{            printf("Possible\n");            double ans=mi;            printf("%.4lf\n",ans);            return 0;        }    }    if (ma<=t){        bool flag=false;        for (int i=1;i<=n;i++){            double x;            if (ma!=t) x=(double)(ma-a[i])*b[i]/(t-ma);            c-=x;            if (c<-0.001||(ma==t&&a[i]<ma)){                flag=true;                break;            }        }        if (flag){            printf("Impossible\n");            return 0;        }        else{             printf("Possible\n");            double ans=ma;            double sum=now+ss-c;            if (c){                ans=(ma*sum+c*t)/(sum+c);            }            printf("%.4lf\n",ans);            return 0;        }    }    return 0;}
阅读全文
0 0
原创粉丝点击