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 <iostream>
#include <cstdio>
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;
}
最后修改:2019 年 02 月 26 日 07 : 58 PM
如果觉得我的文章对你有用,请随意赞赏