蓝桥杯--分巧克力

首先我们来看题目要求:

08a7838e00ea4bd7ad469c0025564a92.pngd228687b42414127a4ab5c82a2f9247d.png

根据题目要求我们知道我们需要找出一个x,满足题目要求(使得K*x*x(分割好的满足条件的面积)<=巧克力总面积),此时通过逆向分析,找到x,我们需要在满足(hi>=1&&wi<=100000)的条件下,查找符合题意的x

因为查找的范围后期会大,我们可以通过二分查找法,缩短查找时间,在hi与wi中查找,以mid=(hi+wi)/2为界限,或往上或往下查找-->定义全局变量--将h,w分别通过数组存储--以mid为界进行二分--传入函数--判断是否满足分的的人数--返回值--若true,则往上查找符合条件的最大值--若false,则往下查找符合的值,以上思路我们通过代码来实现

#include<iostream>
using namespace std;
int N,K;               //定义全局变量,以便在自定义函数中使用 
int h[100000]={0};
int w[100000]={0};
bool judge(int x)     //用judge()函数,判断输入的值是否符合(即是否不超过原面积(h[i]*w[i])),如果是则返回true 
{
	int sum=0;
	int i;
	for(i=0;i<N;i++)             
	{
		sum+=(h[i]/x)*(w[i]/x);     //h[i]/x*w[i]/x=切割好后分得的份数(同时不超过原面积) 
	}
	if(sum>=K)            //即满足题目要求分的份数K时,返回true 
	{
		return true;
	}else{
		return false;
	}
}
int main()
{
	cin>>N>>K;
	int max=0;
	int i;
	for(i=0;i<N;i++)
	{
		cin>>h[i]>>w[i];
	}
	int l,r;    //l为长,即题目中的h[i],r为宽w[i] 
	l=1;        //题目要求(l>=1,w<=100000 
	r=100000;
	while(l<=r)    //当l<=r时进入循环 
	{
		int mid=(r+l)/2;     //二分法缩短查找时间 
		if(judge(mid))       //将中间值mid传入judge()函数进行判断,若符合,即返回true,进行第一条语句 ,查找以mid为分界线的上半部分(查找最大值),否则下半部分 
		{                   
			max=mid;
			l=mid+1;         //继续向>mid上查找,以致结束循环 
		}else{
			r=mid-1;
		}
	}
	cout<<max;
	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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值