最大通过数
思路:假设左边能通过 x 关,右边能通过 y 关,x∈[0,n],通过二分,在前缀和中枚举右边通过的关卡数,保存 x+y 的最大值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,k;int main( ){static_cast<void>(ios::sync_with_stdio(0)),static_cast<void>(cin.tie(0)),cout.tie(0);cin>>n>>m>>k;vector<ll>a(n+1);vector<ll>b(m+1);for(int i=1;i<=n;i++){cin>>a[i];a[i]+=a[i-1];}for(int i=1;i<=m;i++){cin>>b[i];b[i]+=b[i-1];}ll res = 0;for(int i=0;i<=n;i++){if(a[i]>k)break;ll temp =upper_bound(b.begin(), b.end(), k-a[i])-b.begin()-1;res = max(res,temp+i);}cout<<res<<'\n';return 0;
}
妮妮的月饼工厂
思路:假设高度为 x,由于高度越高月饼数越少呈现单调性,所以可以用二分来进行枚举。高度范围是 1-1e9 要开 longlong,就用所有材料是否能做k 个高度为 x 的月饼来进行判断。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll k;
const int N = 1e5+10;
ll a[N];bool check(ll x){ll res = 0;for(int i=1;i<=n;i++){res += a[i]/x;}return res>=k;
}int main( ){cin>>n>>k;ll sum = 0;for(int i=1;i<=n;i++){cin>>a[i],sum+=a[i];}ll l=0,r=1e9;while(l<r){ll mid = (l+r+1)>>1;if(check(mid))l = mid;else r=mid-1;}if(sum<k)cout<<-1<<endl;else cout<<r<<'\n';return 0;
}