2024CCPC济南邀请赛-D(模拟)

题意

王国英雄》是一款点击式冒险游戏,游戏中的主角踏上了拯救父亲的危险旅程,并成为了王国的英雄。

游戏中的钱叫做金币,可以用来购买各种用品,甚至完成某些任务。俗话说,富贵险中求,我们的天才玩家包包就找到了一条致富之路。游戏中有一个磨坊,磨坊主以每袋 p 金币的价格出售面粉。还有一家酒馆,酒保以每袋 q 金( q>p )的价格购买面粉。显然,包包可以将差价收入囊中,但在两个地方之间移动和点击买卖按钮也需要时间。

更确切地说,如果小宝一次从磨坊买入 x 袋面粉,他需要花费 (ax+b)秒和 px 金币;如果小宝一次从酒馆卖出 x 袋面粉,他需要花费 (cx+d) 秒,但却可以赚取 qx 金币。小宝目前有 m 金子,但由于他该睡觉了,他最多只能玩 t 秒。计算他玩完游戏后最多可以拥有的金币数。

思路

由于金币一直在改变,无法找到一个通项公式来直接计算结果,所以需要我们来模拟这个过程。很显然,直接一趟一趟模拟必然会T,所以需要进行一些优化来减少计算过程。

如果\left \lfloor \frac{m}{p} \right \rfloor 的结果相同,每次买卖的结果也是相同的。所以我们将相邻的同种结果合并起来减少循环次数,用一次计算来代替多次循环。

代码

void solve() {
    int p=read(),a=read(),b=read();
    int q=read(),c=read(),d=read();
    int m=read(),t=read();
    if(m<p){//显然 本金买不起货物,直接返回
        cout<<m<<endl;
        return ;
    }
    while(t>0){
        int x=m/p;
        int num1=ceil(1.0*((x+1)*p-m)/(q-p));
        num1=max(num1,x);//计算m/p改变需要交易多少货物,即将m/p相同情况合并
        int num2=ceil(1.0*num1/x);//需要交易多少趟
        num1=max(num1,num2*x);
        int T=num1*(a+c)+num2*(b+d);//需要花费多少时间
        if(t>=T){
            t-=T;
            m+=(q-p)*num1;
        }else{
            num2=t/((a+c)*x+d+b);//剩余时间不够m/p改变,将完整的交易合并
            num1=num2*x;
            T=num1*(a+c)+num2*(b+d);
            t-=T;
            m+=(q-p)*num1;
            if(t-b-d>0){//时间不够一次完整交易,尽可能交易多一些
                num1=(t-b-d)/(a+c);
                m+=(q-p)*num1;
            }
            break;
        }
    }
    cout<<m<<endl;

}

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值