您的位置:首页 > 编程语言

CodeM美团点评编程大赛A轮 C.倒水

2017-06-19 21:26 633 查看
[编程题] 倒水

时间限制:1秒

空间限制:32768K

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

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

注意:一杯温度为t1单位、体积为c1升的水与另一杯温度为t2单位、体积为c2升的水混合后,温度变为(t1*c1+t2*c2)/(c1+c2),体积变为c1+c2。 
输入描述:
第一行一个整数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


输入例子:
3
10 2
20 1
25 1
30 1


输出例子:
Possible
20.0000


题解来自nobody:



官方题解链接:https://www.nowcoder.com/discuss/28582

注意:第一种情况应该是T<=minT

#include <cstdio>
#include <cmath>
using namespace std;
struct jj
{
long long t,c;
}a[100000];
int main()
{
int n,i,flag=0,flag1=0,num=0;	//flag表示是否存在温度比水缸高的水杯,flag1表示是否存在温度比水缸低的水杯,num表示和水缸温度一样的水杯数量
long long t,c,mint,maxt,sum;
double ans,mid,l,r,temp;
scanf("%d",&n);
scanf("%lld %lld",&t,&c);
mint=0x3f3f3f3f;
maxt=0;
for(i=0;n>i;i++)
{
scanf("%lld %lld",&a[i].t,&a[i].c);
if(a[i].t>maxt)
{
maxt=a[i].t;
}
if(a[i].t<mint)
{
mint=a[i].t;
}
if(a[i].t==t)
{
num++;
}
else if(a[i].t>t)
{
flag=1;
}
else
{
flag1=1;
}
}
if(flag==1&&flag1==1&&num!=n)			//在第二种当中的非法情况
{
printf("Impossible");
}
else if(num==n)				//在第二种当中的合法情况
{
printf("Possible\n%.4f",(double)t);
}
else
{
if(mint>=t)		//第一种情况
{
sum=0;
for(i=0;n>i;i++)
{
sum=sum+(a[i].t*a[i].c-a[i].c*mint);
}
if(sum<=c*(mint-t))			//为了避免浮点数产生的误差,这里用乘法代替除法
{
printf("Possible\n%.4f",(double)mint);
}
else			//如果水缸里的水不够用,那么无法达到目的,非法。
{
printf("Impossible");
}
}
else			//第三种情况
{
l=maxt;
r=t;
ans=-1;
flag=1000000/n;
while(flag--)		//二分找最优
{
mid=(l+r)/2;
temp=0;
for(i=0;n>i;i++)
{
temp=temp+(a[i].t*a[i].c-a[i].c*mid)/(mid-t);
}
if(temp>c)
{
r=mid;
}
else
{
l=mid;
ans=mid;
}
}
if(ans==-1)
{
printf("Impossible");
}
else
{
printf("Possible\n%.4f",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: