**
B - Hamburgers
**
做三明治需要面包、香肠和奶酪,用B代表,S代表香肠,C代表奶酪,不同的三明治所含的这三种原料不同。杜老板的厨房现在有有nb块面包,ns块香肠和nc块奶酪。除此之外,这三种原料在附近的商店都有,价格是一片面包pb元,一片香肠ps元,一片奶酪pc元。杜老板有钱,他准备去买。他最多能做多少汉堡?你可以假设它不会破坏或切掉面包、香肠或奶酪的任何一块。除此之外,店里每种原料的数量都是无限量的。
Input
输入的第一行包含一个非空字符串,它描述了三明治的配方。字符串的长度不超过100,字符串只包含字母’B’(英文大写B), ‘S’(英文大写S)和’C’(英文大写C)。
第二行包含三个整数nb, ns, nc(1≤nb, ns, nc≤100)——杜老板的厨房里的面包、香肠、奶酪的块数。
第三行包含三个整数pb, ps, pc(1≤pb, ps, pc≤100)——商店里一片面包、香肠、奶酪的价格。
最后,第四行包含整数r(1≤r≤10^12)——杜老板现在有多少钱。
注意,请不要用% lld,最好使用cin、cout流或%I64d说明符。
Output
打印杜老板能做的三明治的最大数量。如果他做不成,打印0。
Examples
Input
BBBSSC
6 4 1
1 2 3
4
Output
2
Input
BBC
1 10 1
1 10 1
21
Output
7
Input
BSC
1 1 1
1 1 3
1000000000000
Output
200000000001
**思路 **利用二分,寻找能做三文治的最大数量
代码有详细解析;
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
char s[110];
ll have[5];
ll need[5];
ll money[5],cnt;
int sovle(ll mid)
{
ll i,sum=cnt;
for(i=1;i<=3;i++){//枚举每一种配料
ll t=have[i]-need[i]*mid;//t表示的是要做mid个三文治,现在需要购买的数量
if(t<0) sum+=t*money[i];//如果t<0,则证明have不够,需要购买,购买后sum钱数也自然减少
if(sum<0) return 0;//如果 钱数<0了,证明这个方案不成立
}
return 1;//整个购买过程都成立,返回1
}
int main()
{
ll i;
while(~scanf(" %s",s)){
memset(have,0,sizeof(have));
for(i=0;i<strlen(s);i++){//统计三文治的配方,需要的各种数量
if(s[i]=='B'){
need[1]++;
}
else if(s[i]=='S'){
need[2]++;
}
else need[3]++;
}
for(i=1;i<=3;i++){
scanf("%I64d",&have[i]);//have表示本来已经拥有的
}
for(int i=1;i<=3;i++)
scanf("%I64d",&money[i]);//每种食材的单价
ll l=0,r=10e12,ans=0,mid;//一般来说 l,r的区域范围要包括解决办法在内,r可以大一点
scanf("%I64d",&cnt);//拥有的钱
while(l<=r){
mid=(l+r)/2;//mid表示要做多少个三文治
if(sovle(mid)==1){
ans=mid;//更新最优方案
l=mid+1;//这个方案成立,l+1,尝试做更多三文治
}
else r=mid-1;//不能解决,则缩小mid,所以r=mid-1
}
cout <<ans<< endl;
}
}