[Extremely Easy] P10730 [NOISG 2023 Qualification] Burgers
2025/4/19约 573 字大约 3 分钟
简要题意
有两种汉堡, 种食材,食材 有 份。
第一种汉堡需要用 份食材 ,第二种汉堡需要用 份食材 。求出你最大可以做出多少个汉堡。
。
思路
设 表示钦定做 个第一种汉堡,最多可以做出多少个汉堡,那么不难写出式子:
其中值域 。
根据下取整的性质,不难稍作变形:
那么我们需要解决下面一个问题:
给定 个一次函数 ,你需要在给定值域 中找到一个 ,使得 最大。求出这个最大值。
一些比较笨的方法是李超线段树或者凸包,但是更加容易想到的方法是二分这个最大值 ,那么只需要判断 与所有 的交是否为 ,而这是容易的。
时间复杂度 ,其中 为值域。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
using f64 = double;
const f64 eps = 1e-9;
int dcmp(f64 x){ return x < -eps ? -1 : x > eps; }
struct line {
f64 k, b;
} l[N];
int n, a[N], b[N], x[N], maxR;
bool check(f64 v){
f64 L = 0, R = maxR;
for(int i=1;i<=n;i++){
if(!dcmp(l[i].k)){
if(dcmp(v - l[i].b) > 0) return false;
continue;
}
f64 x = (v - l[i].b) / l[i].k;
if(dcmp(l[i].k) == 1) L = max(L, x);
else R = min(R, x);
if(dcmp(L - R) > 0) return false;
}
return ceil(L) <= floor(R);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n, maxR = 1e9;
for(int i=1;i<=n;i++) cin >> x[i];
for(int i=1;i<=n;i++) cin >> a[i], maxR = min(maxR, x[i] / a[i]);
for(int i=1;i<=n;i++) cin >> b[i];
for(int i=1;i<=n;i++) l[i] = {-1.0 * a[i] / b[i] + 1, 1.0 * x[i] / b[i]};
int L = 0, R = 1e9;
while(L < R){
int mid = (L + R + 1) / 2;
if(check(mid)) L = mid;
else R = mid - 1;
}
cout << R << '\n';
return 0;
}
// Written by xiezheyuan