放书 二分+数学

A-Bookshelf Filling_“统信杯” 第十七届黑龙江省大学生程序设计竞赛(正式赛) (nowcoder.com)

题意就是两种类型的书放在一起,分别高a,b,有n,m本,书架高h,现在把b书放在上面的空隙中,问总宽度最小是多少

这个题我刚开始看感觉是模拟题,后来发现模拟的情况太复杂,后来看了题解是二分

后来想一想确实,二分的前提是要有二段性,把枚举巧妙地转化为方案合不合法

这个二分答案,二段性就是分界点的两边,一边是符合情况的,另一边是不符合的,

check函数就是把最大的可以填充的值算出来与x进行比较,如果大于等于x就对的

然后边界问题就是,两边是0到m-1(我就这个错了,然后一直错了,改了就对了)

这个题就是在0,m-1的范围里面,书的本数越大,越不可能,所以如果check符合条件了,那分界点应该在右边,所以l=mid;

#include<iostream>
using namespace std;
typedef long long ll;
ll a,b,n,m,h;
bool check(ll x)
{
    ll ca=(h-a)*(n/b);//注意这里是下整除,就是只有n的数量是b的倍数的时候,才可以把塞进去
    ll cb=(h-b)*((n%b+m-x)/b);//这里就是b上的可供书放的位置*高度
    if(ca+cb>=x) return 1;
    else return 0; 
}
int main(){
    int T;
    cin>>T;
    while(T--)
    {
 
        scanf("%lld%lld%lld%lld%lld",&a,&b,&n,&m,&h);
        int l=0,r=m-1;
        while(l<r)
        {
            ll mid=l+r+1>>1;
            if(check(mid)) l=mid;//这里就是数量越多越塞不下,所以二段性的分界在mid的右边 
            else r=mid-1;
        }
        printf("%d\n",n+m-l);
    }
    return 0;
}
/*
二分:在一定的范围之内,可以根据二分来判断答案的合法性,具有两段性,前半有个部分是塞不进去的,后面的都可以塞进去
很明显的二分
check函数:
如果判断的那个x,小于等于空间里所有占满书的应该数量,那就合法
否则不合法
 
*/

 

posted @ 2022-05-18 15:04  小志61314  阅读(58)  评论(0)    收藏  举报