分巧克力

分巧克力

题目描述

在这里插入图片描述


核心思路

设被分割成的正方形的个数为res,正方形的边长为a,那么有 r e s = W a ∗ H a = W H a 2 res=\dfrac {W}{a}*\dfrac {H}{a}=\dfrac {WH}{a^2} res=aWaH=a2WH。由这个式子可以发现,当边长a增大时,个数res减小;当边长a减小时,个数res增大。也就是说,边长a具有单调性。注意这里说的边长a具有单调性,是说我们分割出来的正方形的边长具有单调性,而不是说题目输入的那个长、宽具有单调性。既然我们切割出来的边长a具有单调性,具有单调性一定可以用二分!!!

所以这道题可以用二分来求解,假设某个边长 x x x是使得刚好能分给K个小朋友,由公式可知,对于所有 ≤ x \leq x x的边长都一定是 ≥ K \geq K K的,那么就是满足题意的,对于所有 > x >x >x的边长都一定是 < K <K <K的,那么就不符合题意。

重新整理一下题意就是:找到 ≤ x \leq x x的所有边长中的最大的那个边长,即最小值的最大,那么就可以用二分模板了。考虑二分的范围:题目说至少可以分得一块 1 × 1 1\times 1 1×1的巧克力,也就是说分割出来的正方形的最小是1。而我们的二分算法就是找边长,因此二分的左范围是1。题目给的长、宽的最大范围是1e5。从实际意义出发,假设我们二分出来的边长大于了输入的最大1e5,那么怎么可能从1e5中分割出比1e5还大的数呢?因此,二分的右范围是1e5。

问题:如何理解 W a ∗ H a \dfrac {W}{a}*\dfrac {H}{a} aWaH就是被分割成的正方形的个数呢?

在这里插入图片描述

问题:如何理解二分模板呢?

在这里插入图片描述


代码

#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e5+10;
//巧克力的长  宽
int h[N],w[N];
int n,k;
//check一下某个边长mid是否能够满足题意
bool check(int mid)
{
    LL res=0;   //切割出的正方形的个数
    for(int i=0;i<n;i++)
    {
        res+=(LL)(h[i]/mid)*(w[i]/mid);
        //能够分给k个小朋友,则满足题意
        if(res>=k)
            return true;
    }
    return false;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%d%d",&h[i],&w[i]);
    //二分的左范围、右范围
    int l=1,r=1e5;
    while(l<r)
    {
        int mid=l+r+1>>1;
        if(check(mid))
            l=mid;
        else
            r=mid-1;
    }
    printf("%d\n",r);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

卷心菜不卷Iris

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

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

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

打赏作者

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

抵扣说明:

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

余额充值