做蛋糕,给出n种原料每种需要多少个才能做一个蛋糕,再给出当前每种原料的库存,最后给你魔法值可以拿来当做任何一种原料,问你最多做几个。
分析:
数据比较大,二分一下就好了。本来水题没什么记录的必要性,这里写二分的时候写二逼了,mid写在前面导致二分0,1时出现bug。D1题里面数据比较弱没触发这个bug,D2里面的第138组数据触发了,debug半天没想到是二分写错了。引以为戒。
再写详细一点,其实就是找出n种原料中,每种原料的库存能够做几份蛋糕。题目用数组a和b表示,那就新建个数组c=b/a来存每种原料的倍数。二分的时候在数组c的最大值与最小值内二分即可,如果魔法值还有剩下,此时二分完原料已经为空,直接凭空做蛋糕即可。这里也可以直接无脑二分,代码量可以少很多,即二分的范围从0-1e9,最终二分的结果当然是正确的,但这样感觉有些暴力,就优化了一些。
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <fstream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=100005;
const int mod=1e9+7;
int a[N],b[N],c[N],n,k;
long long solve(int t) {
long long sum=0,temp;
for (int i=1; i<=n; i++) {
temp=(long long)(t*a[i]-b[i]);
if (temp>0) {
sum+=temp;
}
}
return sum;
}
int main() {
long long sum;
while (cin>>n>>k) {
sum=0;
for (int i=1; i<=n; i++) {
scanf("%d",&a[i]);
sum+=a[i];
}
int minn=INF,maxx=0;
for (int i=1; i<=n; i++) {
scanf("%d",&b[i]);
c[i]=b[i]/a[i];
minn=min(c[i],minn);
maxx=max(maxx,c[i]);
}
int left=minn,right=maxx,mid=left+(right-left)/2,flag = minn+1;
long long temp;
temp=solve(maxx+1);
if (temp<=k) {
right=minn;
flag=maxx+1;
}
while (left<right) {
temp=solve(mid);
if (temp==k) {
break;
} else if (temp>k) right=mid;
else left=mid+1;
mid=left+(right-left)/2;
flag=mid;
}
if (solve(flag)>k) {
flag--;
}
k-=solve(flag);
int s=flag;
if (k>sum) {
s+=k/sum;
}
cout<<s<<endl;
}
return 0;
}