Codeforces 127C Hot Bath

题意:

给出整数t1,t2,x1,x2,t0,和公式(1 ≤ t1 ≤ t0 ≤ t2 ≤ 1061 ≤ x1, x2 ≤ 106).求满足(0 ≤ y1 ≤ x10 ≤ y2 ≤ x2)此条件的y1,y2使得t最接近t0,但要保证t>t0.输出y1,y2.多种方案时输出最大的y1,y2.

题解:不4个特判必WA。不过这4个特判不太容易想全。

case 1:t1==t0 && t2!=t0 => y1=x1,y2=0

case 2:t2==t0 && t1!=t0 => y1=0,y2=x2

case 3:t1==t2 =>y1=x1,y2=x2

做法:

枚举y1,然后t2可以解出来。在选最小的,不过也有坑!见程序吧

case 4:非常难想到的是,当y1==0,方程解出y2=0此时显然不对,所以此种情况仍需处理。

#include<iostream>
#include<cstring>
using namespace std;
long long t1,t2,x1,x2,t0,f1,f2;
long long cal(long long t1,long long y1,long long t2,long long y2)
{
    return t1*y1+t2*y2-t0*(y1+y2);
}
void solve(long long y1,long long y2)
{
    if(y2<0)y2=0;else if(y2>x2)y2=x2;//溢出
    if(y1==0 && y2==0)return;//WA

    if(t1*y1+t2*y2<t0*(y1+y2))return;//不满足t>=t0的条件
    if(cal(t1,y1,t2,y2)*(f1+f2)<cal(t1,f1,t2,f2)*(y1+y2)||(f1<0 && f2<0))
    {
        f1=y1;f2=y2;
    }
    else
    if(cal(t1,y1,t2,y2)*(f1+f2)==cal(t1,f1,t2,f2)*(y1+y2)&&y1+y2>f1+f2)
    {
        f1=y1;f2=y2;
    }
}
int main()
{
    long long y2;
    while(cin>>t1>>t2>>x1>>x2>>t0)
    {
        f1=-1,f2=-1;
        if(t1==t2)//case
        {
            f1=x1;f2=x2;
        }
        else if(t1==t0)//case
        {
            f1=x1;f2=0;
        }
        else if(t2==t0)//case
        {
            f1=0;f2=x2;
        }
        else
        for(long long y1=1;y1<=x1;y1++)
        {
            if(t0>t2)
            {
                y2=(t1*y1-t0*y1)/(t0-t2);
                solve(y1,y2);
            }
            else
            if(t0<t2)
            {
                y2=(t1*y1-t0*y1)%(t0-t2)==0?(t1*y1-t0*y1)/(t0-t2):1+(t1*y1-t0*y1)/(t0-t2);
                solve(y1,y2);
            }
        }
        //y1=0 case 4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        if(t2>=t0)solve(0,x2);

        cout<<f1<<" "<<f2<<endl;
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值