A. Guest From the Past(codeforces)

A. Guest From the Past

问题:你有n元钱,有两种牛奶,一种价值a元,一种价值b元,但回瓶子可以得到c元,两种牛奶不存在差异,问最多买多少瓶牛奶。

我们想让买的牛奶数最多,那每瓶消耗的钱应该是最少的,所以我们就挑每种实际价格小的购买。

但我们还得注意一些小问题
1.假如第二种牛奶每瓶单价较小,但n < b,那我们只能买第一种。
2.因为c < d,如果已经满足上面的条件,那么n就一直在减少,终会出现上面的情况,我们就不能直接用n / (d - c)。
3.如果上面的问题已经解决,那最后n < b一定成立,但n < a不一定成立,所以我们就要再选几瓶第一种牛奶。
4.上面发生的条件都是a > b-c,若a <= b-c,那么我们就可以直接选a,可以直接除。

对于问题2,注释有点写不下就放在这里。
我们可以先选出一个b,然后每次都是先加c,再减b,那么我们就可以直接用除法。
对于n( = n-b)每次先加c再减b,到 n+c < b时,n < b - c。
最后把第一个瓶子的回收费c加上,那么n还满足 n < b的。

看注释

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
    
    
	ll n, a, b, c, t, ans = 0;
	scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
	if(a > b-c) {
    
    
		if(n >= b) {
    
    
		//问题2的解决
			n -= b, ans++;
			ans += n / (b - c); 
			n %= (b - c);
			n += c;
		}
		//问题3 + 问题1
		ans += n/a;
	}
	//问题4
	else ans += n/a; 
	printf("%lld", ans);
	return 0;
}

下面是我第一遍写的代码,用的是循环,Tle了,可以借鉴一下。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
    
    
	ll n, a, b, c, t, ans = 0;
	scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
	if(a > b-c) {
    
    
		while(n >= b) {
    
    
			t = n/b;
			n %= b;
			ans += t;
			n += t*c;//我在这还想ll * ll会不会爆,没想到Tle了。
		}
		ans += n/a;
	}
	else ans += n/a; 
	printf("%lld", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45363113/article/details/106725535