icpc:problems:usaco23feb_bakery_s
problems | |
---|---|
名称 | Bakery S |
题目编号 | USACO23FEB_S1 |
题目链接 | luogu.com.cn/… |
来源 | USACO |
算法分类 | 二分, 数学 |
难易程度 | 一般般 |
Bakery S
想法
可以发现,在题目中x不具备单调性、y不具备单调性、而x+y具有单调性,在x+y的数值分布中,左边为不成立,右边为成立。故二分答案即可。
在判断可行性时,只需要所有不等式满足即可,也就是x有解。可以通过公式推导将所有不等式变为关于x的取值范围,我们取左端点的最大值与右端点的最小值进行比较,如果x存在,则证明二分的答案有解。
代码实现
#include<cstdio> #include<algorithm> #include<cmath> const int N = 110; long long int a[N], b[N], c[N], tc, tm; int n; bool check(long long int mid) { long long int mx = std::max(0LL, mid - tm + 1), mi = std::min(tc-1, mid); for (int i = 0; i < n; ++i) { long long int k = c[i] - a[i] * tc - b[i] * (tm - mid); if(b[i] - a[i] < 0) mx = std::max(mx, (long long int)ceil((double)k / (b[i] - a[i]) )); else if(b[i] - a[i] > 0) mi = std::min(mi, (long long int)floor((double)k / (b[i] - a[i]) )); else if( k < 0 ) return false; } return mx <= mi; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d %lld %lld", &n, &tc, &tm); for (int i = 0; i < n; ++i) scanf("%lld %lld %lld", &a[i], &b[i], &c[i]); long long int l=0, r=(tc+tm), mid; while(l < r) { mid = ( l + r ) / 2; if(check(mid)) r = mid; else l = mid + 1; } printf("%lld\n", l); } return 0; }
/app/www/public/data/pages/icpc/problems/usaco23feb_bakery_s.txt · 最后更改: 2023/05/02 09:51 由 温婕莺