P8647蓝桥杯2017省AB 分巧克力
大家下午好哇,好蛋在这里利用水课的时间整理一下好蛋学校平时的一道编程作业呦~
https://www.luogu.com.cn/problem/P8647
P8647蓝桥杯2017省AB 分巧克力
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
1.形状是正方形,边长是整数 2.大小相同
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?
输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。
输出
输出切出的正方形巧克力最大可能的边长。
样例输入:
2 10
6 5
5 6
样例输出:
2
分析:
我们很容易发现,对于x×y的巧克力,能分离的最大的正方形的边长取决于该矩形最小的边长;并且我们在原先基础上缩小边长可以分出更多的巧克力,但是它们拼起来肯定不会超过最大的那个正方形。
举个例子:假设我们有一个6×5的巧克力,那么能分出最大的巧克力为5×5;再往下分,无论是4×4、3×3、2×2、1×1的巧克力都是基于5×5的巧克力进行分割。
同时我们容易发现,对于任意的x×y的巧克力我们所能分出边长为i的巧克力的数量是(x/i)×(y/i),假如我们有巧克力为6×5,当边长i=3时,我们可以分得(6/3)×(5/3)=2个巧克力;当边长i=2时,我们可以分得(6/2)×(5/2)=6个巧克力。
所以我们对边长进行二分查找,当在该边长下求得的巧克力数量小于需求值时,我们要减小边长,即向左寻找边长。
点击查看代码
#include<stdio.h>
int n, k;
int haha[100000], hehe[100000];
int zeze(int mid)
{
int count = 0;
for (int i = 0; i < n; i++)
{
int a = haha[i] / mid;
int b = hehe[i] / mid;
count = count + a * b;
}
if (count >= k)
{
return 1;
}
return 0;
}
int main()
{
scanf("%d %d", &n, &k);
for (int i = 0; i < n; i++)
{
scanf("%d %d", &haha[i], &hehe[i]);
}
int l = 1, r = 100000000000, mid;
while (l < r)
{
mid = (l + r + 1) / 2;
if (zeze(mid))
{
l = mid;
}
else
{
r = mid - 1;
}
}
printf("%d", l);
return 0;
}
点击查看代码
#include<stdio.h>
int haha[1000010], hehe[1000010];
int max(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int n, k;
scanf("%d %d", &n, &k);
int l = n,w = 1;
for (int i = 1; i <= n; i++)
{
scanf("%d %d", &haha[i], &hehe[i]);
l = max(l, max(haha[i], hehe[i]));
}
for (int i = 1; i <= l; i++)
{
int o = 0;
for (int j = 1; j <= n; j++)
{
o += (haha[j] / i) * (hehe[j] / i);//计算
if (o >= k) break;
}
if (o < k) break;
w = i;
}
printf("%d", w);
return 0;
}
浙公网安备 33010602011771号