题意
王国英雄》是一款点击式冒险游戏,游戏中的主角踏上了拯救父亲的危险旅程,并成为了王国的英雄。
游戏中的钱叫做金币,可以用来购买各种用品,甚至完成某些任务。俗话说,富贵险中求,我们的天才玩家包包就找到了一条致富之路。游戏中有一个磨坊,磨坊主以每袋 p 金币的价格出售面粉。还有一家酒馆,酒保以每袋 q 金( q>p )的价格购买面粉。显然,包包可以将差价收入囊中,但在两个地方之间移动和点击买卖按钮也需要时间。
更确切地说,如果小宝一次从磨坊买入 x 袋面粉,他需要花费 (ax+b)秒和 px 金币;如果小宝一次从酒馆卖出 x 袋面粉,他需要花费 (cx+d) 秒,但却可以赚取 qx 金币。小宝目前有 m 金子,但由于他该睡觉了,他最多只能玩 t 秒。计算他玩完游戏后最多可以拥有的金币数。
思路
由于金币一直在改变,无法找到一个通项公式来直接计算结果,所以需要我们来模拟这个过程。很显然,直接一趟一趟模拟必然会T,所以需要进行一些优化来减少计算过程。
如果 的结果相同,每次买卖的结果也是相同的。所以我们将相邻的同种结果合并起来减少循环次数,用一次计算来代替多次循环。
代码
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;
}