P8647 [蓝桥杯 2017 省 AB] 分巧克力

题目描述

儿童节那天有 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 块巧克力,其中第 块是 的方格组成的长方形。

为了公平起见,小明需要从这 块巧克力中切出 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数。

  2. 大小相同。

例如一块 的巧克力可以切出 块 的巧克力或者 块 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

输入格式

第一行包含两个整数 和 。。

以下 行每行包含两个整数 和 。。

输入保证每位小朋友至少能获得一块 的巧克力。

输出格式

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

输入输出样例 #1

输入 #1

2 10  
6 5  
5 6  

输出 #1

2

说明/提示

蓝桥杯 2022 省赛 A 组 I 题。

解析

这个题应该算是比较基础,我们观察题目可以得到他的意思是让我们去求解最大边长,那么最大数据可以到10^5^ ,如果仅仅是暴力搜索肯定会超时,那么我们就要采取其他策略,如果边长是,切出的块数如果大于等于,那么更小的边长一定也够分,那么就可以观察到一个明显的单调效应,那么我们就可以采取二分策略

那么现在,我们就要面临怎样去计算这个方块可以被物理切除切成边长为的正方形,你整个面积撑起来肯定是不可以的,我们要做的就是整数除法,即,这样才能算出这一块可以剪出多少个方块

剩下的就是简单的二分

代码

//
// Created by 23264 on 2026/2/22.
//
#include<bits/stdc++.h>
using namespace std;
 
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
 
int n,k;
vector<vector<int>> Cho;
 
bool check(int x)
{
    int ans = 0;
    for (int i = 0;i < n;i++)
    {
        ans += (Cho[i][0] / x) * (Cho[i][1] / x);
    }
    return ans >= k;
}
 
void solve()
{
    int l = 1,r = 10002;
    while (l < r)
    {
        int mid = (l + r + 1) / 2;
        if (check(mid))
        {
            l = mid;
        }
        else
        {
            r = mid - 1;
        }
    }
    cout << l << endl;
}
 
int main()
{
    IOS;
    cin >> n >> k;
    Cho.resize(n,vector<int>(2));
    for (int i = 0;i < n;i++)
    {
        cin >> Cho[i][0] >> Cho[i][1];
    }
    solve();
}