CodeForces 371C Hamburgers 二分

CodeForces 371C Hamburgers 二分

题意

给你一个做汉堡包的菜单,他们是由B S C,三种材料做成的,现在我们有一些材料和钱,我们想做最多的汉堡包,请问最多是多少?

解题思路

这里我们开始我们可能会想该怎么买,也就是买的策略是什么,其实我们可以不用去思考这个,理由如下:

假如我们知道最后的结果,我们是不是可以算出来我们要买的东西?答案是肯定的(在钱不浪费的情况下),再加上这个答案是线性单调的,也就是如果答案是m,那么小于m的也是一定可以做到的,这样我们就可以使用二分来枚举答案了。

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const ll llinf=2000000000000;//12个零 
const int MAXN=1E6+7;
char recipe[227];
ll need[4], nums[4], price[4], r=0;
bool solve(ll x)
{
	ll B=x*need[1], S=x*need[2], C=x*need[3];
	ll tmp1=0, tmp2=0, tmp3=0; //每个需要买的材料花费的金额,最好是分开存储。因为有可能会溢出。
	if(nums[1] < B)
		tmp1= (B - nums[1])*price[1];
	if(nums[2] < S)
		tmp2= (S - nums[2]) * price[2];
	if(nums[3] < C)
		tmp3= (C - nums[3]) * price[3];
	if(tmp1+tmp2+tmp3 <= r)
		return true;
	else return false;
}
int main()
{
	cin>>recipe;
	for(int i=0; i<strlen(recipe); i++)
	{
		if(recipe[i]=='B')
			need[1]++;
		else if(recipe[i]=='S')
			need[2]++;
		else if(recipe[i]=='C')
			need[3]++;
	}
	for(int i=1; i<=3; i++)
		cin>>nums[i];
	for(int i=1; i<=3; i++)
		cin>>price[i];
	cin>>r;
	ll left=0, right=llinf; //这里的答案最大值不能太大,因为solve函数中由乘法,可能会溢出,很难受。
	while(left < right)
	{
		ll mid=left+(right-left)/2;
		if(solve(mid))
			left=mid+1;
		else right=mid;
	}
	if(left==0)
		cout<<0<<endl;
	else cout<<left-1<<endl;
	return 0;
}
posted @ 2020-02-03 12:39  ALKING1001  阅读(100)  评论(0编辑  收藏  举报