题目
输入样例:
2 10
6 5
5 6
输出样例:
2
思路
观察数据范围,时间复杂度要限制在O(n logn)以内,同时观察到“每位小朋友至少能获得一块1×1的巧克力”,说明只要巧克力边长缩小到一定长度,一定有解。这个很容易证明:假设要切边长为s的小块巧克力,那么一块巧克力在H上可以切
块,在W上可以切
块,一共可以切
个小块;随着s减小,那么可以切的总块数会增加。
因此本题可以利用这个性质来使用二分来做。边长的可能范围为1~100000。对于每个可能符合条件的边长,使用这个边长来分割N块巧克力,看分割出来的巧克力块数是否大于等于K。
代码
#include<bits/stdc++.h>
#define h first
#define w second
using namespace std;
const int N = 1e5 + 10;
typedef pair<int,int> PII;
PII a[N];
int n, k;
int Max(int a, int b)
{
return a > b ? a : b;
}
bool check(int mid)
{
int total_num = 0;
//每块巧克力能分多少mid那么大的块
for (int i = 1; i <= n; i ++)
{
total_num += ((a[i].h / mid) * (a[i].w / mid));
if(total_num >= k) return true;
}
return false;
}
int main()
{
scanf("%d%d", &n, &k);
int l = 1, r = 0;
for (int i = 1; i <= n; i ++)
{
scanf("%d%d", &a[i].h, &a[i].w);
r = Max(Max(a[i].h, a[i].w), r);
}
while (l < r)
{
int mid = (l + r + 1) >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
printf("%d", l);
return 0;
}