题目描述如下
对于满足某个条件的单调最值问题,我们应该下意识考虑二分,我们分析本题的条件,要找一个边长最大值使得我们所有的巧克力切出该边长的正方形的数量大于等于人数,由于我们的边长一定在1到1e5之间,我们要在这个单调区间内找到一个满足条件的最大值
那么我们二分的范围和check函数就很容易能写出来了,接下来数据一存就结束了(自从学了二元组,感觉俩数据但凡有点关系就想拿二元组数组存,比如本题的长和宽能拿两个数组存,但二元组真的好直观)
本题还有一个数学方面的思考,就是给定长,宽和正方形的边长,怎么求该长方形内最多能有几个该正方形呢,其实由于除法向下取整的性质,我们直接(长/边长)*(宽/边长),//由于分别是长和宽能容纳的最大边长个数,相乘就是该二维长方形能容纳正方形的个数
这么看来,蓝桥ac三四个稳省一,其中的一个也就不过如此
ac代码如下
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k;
typedef pair<int,int> pii;//存长和宽
pii a[N];//二元组数组,存多组长和宽
bool check(int x){
int sum=0;//存n个蛋糕能切出边长为x的正方形最大个数
for(int i=0;i<n;i++){
sum=sum+(a[i].first/x)*(a[i].second/x);
}
if(sum>=k) return true;
else return false;
}
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
int l,w;
cin>>l>>w;
a[i]={l,w};
}
//二分板子,最基本算法,不会去学,这里不详细展开
int l=1,r=1e5;
while(l<r){
int mid=l+r+1>>1;
if(check(mid)) l=mid;/*如果该结果可行,那么找大于等于他的边长行不行(因为要找最大边长)*/
else r=mid-1;
}
cout<<l;
}