贪心???
题目描述
有一个大水缸,里面的水温度为T单位,体积为C升。另有n杯水,每杯的温度为ti单位,体积为ci升,现在你要将大水缸的水倒入n杯水中使得n杯水的温度相同(不一定倒完),请问这是否可能?如果可能,输出可以达到的最高温度。
注意:一杯温度为t1单位,体积为c1升的水与一杯温度为t2单位,体积为c2升的水混合后的温度为(t1c1+t2c2)/(c1+c2)单位,体积为c1+c2升。
输入格式
第一行一个整数n。 第二行两个整数T,C。 接下来nn行每行两个整数ti,ci,分别表示温度与体积。
输出格式
如果不可能,输出Impossible,否则第一行输出Possible,第二行输出最高温度(保留4位小数)
样例数据
input
3
10 2
20 1
25 1
30 1
output
Possible
20.0000
数据规模与约定
时间限制:1s
空间限制:256M
本题有部分分,正确输出第一行得到当前测试点40%的分数
对于60%的数据:n≤100 ; T,ti≤10n≤100 ; T,ti≤10
对于100%的数据:n≤105 ; 0≤T,ti≤104 ; 0≤C≤109
思路:分三种情况讨论。
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仍有剩余,就把剩下的都加进去,计算最后的温度即为答案。
注意特判max[i]=t和min[i]=t的情况,不然会RE(除以0)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100000
using 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=(a[i]-mi)*b[i]/(mi-t);
c-=x;
if (c<0){
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=(ma-a[i])*b[i]/(t-ma);
c-=x;
if (c<0){
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;
}