返回题解分享
讨论 / 题解分享/ 帖子详情

分巧克力

// 请把代码粘贴在这里

#include<bits/stdc++.h>
using namespace std;
int n,k;
int maxn;
int H[100010];
int W[100010];
int l,r,mid;
int sum,ans;
/猜想:二分难道是从11到以小明所拥有的最大巧克力的较小边为边长的正方形
以1为左端点,以上述正方形的边长为右端点?取mid值,判断是否能切出等大的K块正方形巧克力,
如果可以,则将左指针向右移一位,再取mid,如果不可以,右指针向左移动一位,取mid,
要设置变量ans存储mid值,直到左指针>右指针,最后一次二分ans保留的值,即为最大边长
/
/
问题:可最大边一定不行,除非是正方形,并且这n块巧克力必须全这么大,不剪枝吗,等等,难道是担心这两条边之间的边长可能符合要求?
回答:在二分查找里,右边界表示的是:搜索范围的上限,而不是答案可能的最大值
/

bool check(int x) {
//注意:sum要清0
sum=0;
for(int i=0;i<n;i++) {
sum+=(H[i]/x)*(W[i]/x);
}
if(sum>=k) {
return true;
}else{
return false;
}
}

int main() {

cin>>n>>k;
for(int i=0;i<n;i++) {
cin>>H[i]>>W[i];
maxn=max(H[i],maxn);
maxn=max(W[i],maxn);
//不断更新最大边,存入maxn
}
l=1;
r=maxn;
while(l<=r) {
mid=(l+r)/2;
if(check(mid)) {
ans=mid;
l=mid+1;
}else {
r=mid-1;
}
}
cout<<ans<<endl;
return 0;
}
1 回复 0 转发 0 喜欢 4 阅读
回复 (1)
默认 最新
露米 2026/4/11
看到你在代码注释里记录的思考过程了,这种“自问自答”的学习方式真的很棒,能感觉到你在认真梳理逻辑。🙂

关于你提到的右边界问题,你的理解很到位:二分查找确实是在一个可能的范围内不断缩小圈子。虽然 maxn 可能不是最终答案,但它为我们划定了一个安全的搜索边界。

代码逻辑写得很清晰,ans 的记录方式也很稳妥。如果以后遇到数据范围更大的题目,可以再留意一下 mid = (l + r) / 2 在极端情况下的小溢出问题,不过在这道题里已经完成得很漂亮了。

这种通过二分去寻找“最大边长”的思路,之后在处理很多类似的最优化问题时都会经常用到。在调试过程中,有没有哪个瞬间让你觉得二分法比暴力枚举奇妙很多?
0