Educational Codeforces Round 88 (Rated for Div. 2) 参赛人数19992
[codeforces 1359C] Mixing Water 公式推导+浮点数化整数+绝对值脱壳的4种形态
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1359/problem/C
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Mixing Water | GNU C++17 | Accepted | 46 ms | 200 KB |
公式推导如下
2种情况:
1.热水与冷水杯数一致,都是x杯
t=(h*x+c*x)/(x+x)
化浮点数运算为整数运算
h*x+c*x=t*(x+x)
h+c=2*t
x可以取任意值,那么,此时最小值x=1,故输出2
2.热水比冷水多1杯,热水是x杯,冷水是x-1杯
t=(h*x+c*(x-1))/(x+x-1)
h*x+c*(x-1)=t*(x+x-1)
x=(t-c)/(2*t-(h+c))
2.1讨论
2.1.1分母若为0,无结果,即2*t-(h+c)==0无结果,正好对应情况1,此时x=1,故输出2
2.1.2若分母小于0,则x小于0,此时最小值x=1,故输出2
即2*t-(h+c)<=0,输出2
2.2讨论
除去2.1讨论的情况,
x=(t-c)/(2*t-(h+c))
2.2.1若t-c能整除2*t-(h+c),那么输出x+x-1
2.2.2若t-c不能整除2*t-(h+c),那么x1=(t-c)/(2*t-(h+c)),x2=(t-c)/(2*t-(h+c))+1
输出哪个呢?
接下来讨论涉及绝对值脱壳的4种情况
将求出的x1带回t=(h*x+c*(x-1))/(x+x-1)
得到t1=(h*x1+c*(x1-1))/(x1+x1-1)
将求出的x2带回t=(h*x+c*(x-1))/(x+x-1)
得到t2=(h*x2+c*(x2-1))/(x2+x2-1)
目标若:
|t1-t|<=|t2-t|选x1,反之,选x2
如何判定t1,t浮点数大小关系,技巧如下,对浮点数t1=(h*x1+c*(x1-1))/(x1+x1-1)进行取整
若在整数范畴t1==t,可以判定浮点数范畴t1>=t
若在整数范畴t1<t,可以判定浮点数范畴t1<t
如何判定t2,t浮点数大小关系,技巧如下,对浮点数t2=(h*x2+c*(x2-1))/(x2+x2-1)进行取整
若在整数范畴t2==t,可以判定浮点数范畴t2>=t
若在整数范畴t2<t,可以判定浮点数范畴t2<t
t1,t2,t之间关系,存在4种情况
情况1:t1<=t,t2<=t
绝对值脱壳
t-t1<=t-t2
即t-(h*x1+c*(x1-1))/(x1+x1-1)<=t-(h*x2+c*(x2-1))/(x2+x2-1)
整理(h*x2+c*(x2-1))/(x2+x2-1)<=(h*x1+c*(x1-1))/(x1+x1-1)
化浮点数运算为整数运算
(h*x2+c*(x2-1))*(x1+x1-1)<=(h*x1+c*(x1-1))*(x2+x2-1)
上述情况满足,选x1,反之,选x2
情况2:t1>=t,t2>=t
绝对值脱壳
t1-t<=t2-t
即(h*x1+c*(x1-1))/(x1+x1-1)-t<=(h*x2+c*(x2-1))/(x2+x2-1)-t
整理(h*x1+c*(x1-1))/(x1+x1-1)<=(h*x2+c*(x2-1))/(x2+x2-1)
化浮点数运算为整数运算
(h*x1+c*(x1-1))*(x2+x2-1)<=(h*x2+c*(x2-1))*(x1+x1-1)
上述情况满足,选x1,反之,选x2
情况3:t1<=t,t2>=t
绝对值脱壳
t-t1<=t2-t
即2*t<=(h*x1+c*(x1-1))/(x1+x1-1)+(h*x2+c*(x2-1))/(x2+x2-1)
化浮点数运算为整数运算
2*t*(x1+x1-1)*(x2+x2-1)<=(h*x1+c*(x1-1))*(x2+x2-1)+(h*x2+c*(x2-1))*(x1+x1-1)
上述情况满足,选x1,反之,选x2
情况4:t1>=t,t2<=t
绝对值脱壳
t1-t<=t-t2
即2*t>=(h*x1+c*(x1-1))/(x1+x1-1)+(h*x2+c*(x2-1))/(x2+x2-1)
化浮点数运算为整数运算
2*t*(x1+x1-1)*(x2+x2-1)>=(h*x1+c*(x1-1))*(x2+x2-1)+(h*x2+c*(x2-1))*(x1+x1-1)
上述情况满足,选x1,反之,选x2
AC代码如下(建议结合上述分析,进行理解)
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
int main(){
LL T,h,c,t,d,x,b,x1,x2,p,q,y,z,e,f;//怕溢出,统统用long long省事
scanf("%lld",&T);
while(T--){
scanf("%lld%lld%lld",&h,&c,&t);
d=2*t-(h+c);
if(d<=0){printf("2\n");continue;}//分母小于等于0
b=t-c;
if(b%d==0){x=b/d,printf("%lld\n",x+x-1);continue;}
x1=b/d,x2=b/d+1;
p=2*x1-1,q=2*x2-1,y=h*x1+c*(x1-1),z=h*x2+c*(x2-1);
e=(LL)(y/p),f=(LL)(z/q);
if(e<t&&f<t){//绝对值脱壳
if(z*p<=y*q)x=x1;
else x=x2;
}else if(e>=t&&f>=t){//绝对值脱壳
if(y*q<=z*p)x=x1;
else x=x2;
}else if(e>=t&&f<t){//绝对值脱壳
if(y*q+z*p<=2*t*p*q)x=x1;
else x=x2;
}else if(e<t&&f>=t){//绝对值脱壳
if(2*t*p*q<=y*q+z*p)x=x1;
else x=x2;
}
printf("%lld\n",x+x-1);
}
}