刷题记录:牛客NC13228倒水

传送门:牛客

有一个大水缸,里面水的温度为T单位,体积为C升。另有n杯水(假设每个杯子的容量是无限
的),每杯水的温度为t[i]单位,体积为c[i]升。
现在要把大水缸的水倒入n杯水中,使得n杯水的温度相同,请问这可能吗?并求出可行的最高
温度,保留4位小数。
注意:一杯温度为t1单位、体积为c1升的水与另一杯温度为t2单位、体积为c2升的水混合后,
温度变为(t1*c1+t2*c2)/(c1+c2),体积变为c1+c2。
输入:
3
10 2
20 1
25 1
30 1
输出:
Possible
20.0000

主要思路:

  1. 首先这道题第一眼看去就想到了二分求解,但是如果没有想到贪心的方法的话直接暴力二分的话可能会被保留四位小数的设置所迷惑(我感觉就是来迷惑二分求解的),可能会使用浮点数二分的方法,这个时候我们又会觉得精度又成了问题,题目并没有告诉我们二分精度啊,注意这个保留四位小数不一定就是二分精度,我应该保留后面两位还是一位呢,会不会出现一些sb一样的细节问题??,并且二分之后每一次的判断都是一个循环,感觉有点复杂(当然肯定是可以做的)
  2. 但是在想到二分时,我们不妨继续想一下贪心该怎么做(不要问我为什么一直抓着贪心不放,问就是这道题是在贪心的题集里刷到的),我们想了一下就会发现这样的一个事实,因为各个杯子里面的水是无法互相混合的,那就是说我们先计算出每一杯水的平均温度t(包括水桶的),如果t在各个杯子的最大值和最小值之间的话,我们就是没办法做到的,为什么呢,主要是因为这种情况下平均温度是在两者之间的话,如果大水缸的温度比min小说明大水缸并不足以使比最低温高的水温降到比最低温低或者相等,而大水缸与最低温混合温度又是肯定比最低温低的,所以矛盾,反之如果大水缸的温度比max高也是一样,如果大水缸的温度在两者之间,那就更加不可能了(因为大水缸与最小值混合<=大水缸的温度,与最大值混合<=最大值的温度,不可能使其相等)
  3. 所以只有两种可行情况:假如平均的水温比n个杯子里的都小,那么肯定大水缸是降温的.假如平均的水温比最大的要大,说明大水缸是升温的,升温升到平均温度,降温降到最小温度即可
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <stack>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
	ll x=0,w=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*w;
}
#define maxn 1000000
double t[maxn],c[maxn];
int main() {
	int n;double T,C;
	n=read();T=read();C=read();
	double sumt=T*C,sumc=C;double maxt=-1e9,mint=1e9;
	for(int i=1;i<=n;i++) {
		t[i]=read();c[i]=read();
		sumt+=t[i]*c[i];sumc+=c[i];
		maxt=max(maxt,t[i]);
		mint=min(mint,t[i]);
	}
	double temp=sumt/sumc;
	if(temp<=mint) {
		cout<<"Possible"<<endl;
		printf("%.4f\n",mint);
	}
	else if(temp>=maxt) {
		cout<<"Possible"<<endl;
		printf("%.4f\n",temp);
	}
	else {
		cout<<"Impossible"<<endl;
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值