分巧克力、扫地机器人(二分)

分巧克力“蓝桥杯”练习系统 (lanqiao.cn)

 

解析:公式:(长/当前最大边长)*(宽/当前最大变长),这个很容易推出来的。就比如6 * 5划成

2 * 2,有(6/2)*(5/2)= 6块。根据这个公式进行二分答案即可

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL s,n,k;
int h[100005],w[100005];

bool check(int x) {
	int cnt=0;
	for(int i=1; i<=n; i++)
		cnt+=(h[i]/x)*(w[i]/x);//由样例中可得此式子 
	return cnt>=k;//与题意相符才为真 
}

int main() {
	int ans,l=1,r=1;
	cin>>n>>k;
	for(int i=1; i<=n; i++) {
		cin>>h[i]>>w[i];
		r=max(r,max(h[i],w[i]));//减少一点工作量(最大也只能切成这样,可能还切不出) 
	}
	while(l<=r) {
		int mid=(l+r)/2;
		if(check(mid)) {
			ans=mid;
			l=mid+1;//最大边长太小了,往右边继续找
		} else r=mid-1;//太大了,左边找
	}
	cout<<ans;
	return 0;
}

扫地机器人“蓝桥杯”练习系统 (lanqiao.cn)

 

解析:二分,用check找区间长度,判定方式需要分类讨论,代码有解释

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int n,k;
int a[100005];
//求小于等于的最大值 
//s是到达的位置,x是需要扫的长度 
bool check(int x) {
	int s=0;//清扫到哪个位置 
	for(int i=1; i<=k; i++) {
		if(a[i]<=s+x) { //a[i]在需要扫的范围内 
			if(a[i]<=s) s=a[i]+x-1; //a[i]一开始就开始扫描位置的左侧,记得减去自己 
			else s+=x;//a[i]在s右边,左边还需要扫,所以相当于s+x 
		}
		else return false;//a[i]>=s+x表示区间长度太短了,够不着 
	}
	return s>=n;
}

int main() {
	cin>>n>>k;
	for(int i=1; i<=k; i++)
		cin>>a[i];
	sort(a+1,a+k+1);
	int l=1,r=n,ans;
	//二分板 
	while(l<=r) {
		int mid=l+(r-l)/2;
		if(check(mid)) {
			ans=mid;
			r=mid-1;//大了往左靠 
		}
		else l=mid+1;//小了往右靠 
	}
	cout<<(ans-1)*2;
	return 0;
}

### 蓝桥杯分巧克力问题的Python解题思路 #### 1. 题目分析 题目描述了儿童节那天有K位小朋友到小明家做客,而小明拿出N块不同大小的巧克力来招待他们。每一块巧克力由Hi x Wi组成,目标是在满足每位小朋友至少获得一定面积的情况下,使得切割出来的最大可能面积最大化。 为了高效解决问题并避免超时,在处理大数据集时采用二分查找方法可以显著提高效率[^3]。 #### 2. 思路解析 通过设定合理的边界条件来进行二分搜索,具体来说就是确定能够分配给每个孩子的最小正方形边长范围,并在此基础上不断调整直至找到最优解: - **初始化上下限**:设`low=0`, `high=min(min(H),min(W))`作为初始搜索区间; - **计算中间值mid=(low+high)/2**, 并统计当前条件下能否恰好切成k份及以上; - 如果能,则尝试更大的尺寸(`low=mid`);反之则缩小尺寸(`high=mid`); - 当`high-low<=1`停止循环, 此时`low`即为所求的最大化后的单个孩子可得巧克力面积. 此过程不仅利用到了经典的二分查找技巧还结合实际情况进行了适当变通以适应特定需求[^1]. #### 3. Python代码实现 以下是基于上述逻辑编写的Python版本解决方案: ```python def can_divide(chocolates, mid, k): count = sum((h // mid) * (w // mid) for h, w in chocolates) return count >= k def max_square_area(N, K, H, W): chocolates = list(zip(H, W)) low, high = 0, min(min(H), min(W))+1 while high - low > 1: mid = (low + high) >> 1 if can_divide(chocolates, mid, K): low = mid else: high = mid return low if any(h >= low and w >= low for h,w in chocolates) else 0 # 输入部分 n,k = map(int,input().split()) H,W=[],[] for _ in range(n): hi,wi=map(int,input().split()) H.append(hi);W.append(wi) print(max_square_area(n,k,H,W)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_谦言万语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值