LQB2017A06 分巧克力

(二分啊,,,还是多刷题吧,包括以前的一些算法,感觉根本就没有学深)

标题: 分巧克力

儿童节那天有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

 

 

 

 

可以用线性,但是据说会超时

所以用了二分呢

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;

int n,k;
int h[100005],w[100005];

bool check(int m)
{
    int sum=0;
    for(int i=0;i<n;i++)
    {
        sum+=(h[i]/m)*(w[i]/m);
        if(sum>=k)
            return true;
    }
    return false;
}

int main()
{
    cin>>n>>k;
    int l=1,r=0;
    for(int i=0;i<n;i++)
    {
        cin>>h[i]>>w[i];
        if(h[i]>r)
            r=h[i];
        if(w[i]>r)
            r=w[i];
    }
    while(l<=r)
    {
        int m=(l+r)/2;
        if(check(m))
            l=m+1;
        else
            r=m-1;
    }
    while(l)//检验是否正确
    {
        if(check(l))
            break;
        l--;
    }
    cout<<l<<endl;
    return 0;
}

二分其实还是挺重要的,害,等再找几个题瞅瞅

posted @ 2020-10-01 10:16  安之若醇  阅读(147)  评论(0编辑  收藏  举报
Live2D服务支持