儿童节那天有 K
位小朋友到小明家做客。
小明拿出了珍藏的巧克力招待小朋友们。
小明一共有 N
块巧克力,其中第 i 块是 Hi×Wi
的方格组成的长方形。
为了公平起见,小明需要从这 N
块巧克力中切出 K
块巧克力分给小朋友们。
切出的巧克力需要满足:
形状是正方形,边长是整数
大小相同
例如一块 6×5
的巧克力可以切出 6 块 2×2 的巧克力或者 2 块 3×3
的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
输入格式
第一行包含两个整数 N
和 K
。
以下 N
行每行包含两个整数 Hi 和 Wi
。
原题如下
输入保证每位小朋友至少能获得一块 1×1
的巧克力。
输出格式
输出切出的正方形巧克力最大可能的边长。
数据范围
1≤N,K≤105
,
1≤Hi,Wi≤105
输入样例:
2 10
6 5
5 6
输出样例:
2
难度: 简单
时/空限制: 1s / 64MB
总通过数: 2631
总尝试数: 5170
来源: 第八届蓝桥杯省赛C++A/B组,第八届蓝桥杯省赛JAVAA/B组
算法标签
二分
题目分析
思路同浮点二分,不过代码实现有一点不同。
通过代码
解法一
#include<stdio.h>
#include<iostream>
using namespace std;
int a[(int)1e5+10][2];
int n,k;
int l=1,r=1e5;
bool check(int mid){
long long sum=0;
for(int i=1;i<=n;++i){
sum+=(a[i][1]/mid)*(a[i][0]/mid);
if(sum>=k) return true;
}
return false;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>a[i][0];
cin>>a[i][1];
}
while(l<r){
int mid=(l+r)/2+1//向上取整,则mid包括在左区间;
if(check(mid)){
l=mid;
}
else r=mid-1//为了避免死循环,r减一;
}
cout<<r<<endl;
return 0;
}
解法二
#include<stdio.h>
#include<iostream>
using namespace std;
int a[(int)1e5+10][2];
int n,k;
int l=1,r=1e5;
bool check(int mid){
long long sum=0;
for(int i=1;i<=n;++i){
sum+=(a[i][1]/mid)*(a[i][0]/mid);
if(sum>=k) return true;
}
return false;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>a[i][0];
cin>>a[i][1];
}
while(l<r){
int mid=(l+r)/2//向下取整,则mid包括在右区间;
if(check(mid)){
l=mid+1;//为了避免死循环,l加一;
}
else r=mid
}
cout<<r-1<<endl;//此解法会导致解多1,减去 推荐解法一。
return 0;
}
yxc大佬的模板
大佬在模板一中结果忘了减一qwq