Description

儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。  小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
形状是正方形,边长是整数
大小相同
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?

Input

第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。

Output

输出切出的正方形巧克力最大可能的边长。

Sample Input 1
2 10 6 5 5 6
Sample Output 1
2
Source
蓝桥杯历届试题
题目有点抽象,根本就看不出是用的二分法。

主要有两点一个就是二分法,一个就是一个大的能分成 Hi/m*Wi/m个m*m的正方形。

include

include

using namespace std;
class qkl{
public:
int x;
int y;
};
int main()
{
qkl myQkl[100000];
int n,k;
int max = 0,min = 1;
int mid = 0;
cin >> n >> k;

for(int i=0;i<n;i++)
{
cin >> myQkl[i].x >> myQkl[i].y;
if(myQkl[i].x < myQkl[i].y) //保证x>=y
{
int t = myQkl[i].x;
myQkl[i].x = myQkl[i].y;
myQkl[i].y = t;
}

if(myQkl[i].y>max)
{
  max = myQkl[i].y;
}

}

max+=1; //保证结果完全正确 这是一个重要的地方,否则A不全

while(max-1>min) //结束条件
{
int sum = 0;
mid = (min+max) / 2;
for(int i=0;i<n;i++)
{
sum+=(myQkl[i].x/mid)*(myQkl[i].y/mid);
}
if(sum>=k)
{
min = mid;
}
else
{
max = mid;
}
}
cout << min << endl;
return 0;
}

最后修改:2022 年 04 月 01 日
如果觉得我的文章对你有用,请随意赞赏