装备合成

原题链接

通过集思广益,我总结了一些不同的解法。

法一:二分答案

一般最大最小值问题都可以考虑一下对答案进行二分。

1、若能合成k件装备,那么k-1,k-2,...都能够合成。所以我们要找到11110000中最右边的1。

2、判断k件装备能否成立。设消耗的2a3b有m件,那么4a1b的有k-m件

列不等式0<=2m+4(k-m)<=x      0<=3m+k-m<=y       0<=m<=k且m为整数

化简得4k-m<=2m<=2k        0<=2m<=y-k且m为整数

即max(4k-m,0)<=2m<=min(y-k,2k)

另外由于m是整数,2m为偶数,所以如果max(4k-m,0)=min(y-k,2k)且为奇数,也是不符合的。

主要代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x,y;
bool check(ll m){
    ll l=max(4*m-x,ll(0)),r=min(2*m,y-m);
    if (l<r) return true;
    else if (l==r && l%2==0) return true;
    else return false;
}
int main(){
    int t;
    cin>>t;
    while (t--){
        cin>>x>>y;
        ll left=0,right=y+1;
        while (left+1<right){
            ll mid=left+(right-left>>1);
            if (check(mid)) left=mid;
            else right=mid;
        }
        printf("%lld\n",left);
    }
    return 0;
}

 

法二:线性规划或者说观察单调性。如图

主要代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x,y;
int check(ll m){
    ll n=min((x-2*m)/4,y-3*m);
    return m+n;
}
int main(){
    int t;
    cin>>t;
    while (t--){
        cin>>x>>y;
        ll m3;
        double m=1.0*(4*y-x)/10;
        m3=min(x/2,y/3);
        if (m3<m) printf("%d\n",m3);
        else if (m<=0) printf("%d\n",y); 
        else {
            ll m1=floor(m),m2=ceil(m);
            m1=check(m1);
            m2=check(m2);
            if (m1>m2) printf("%lld\n",m1);
            else printf("%lld\n",m2);
        }        
    }
    return 0;
}

法三:三分(ps:现在还不会三分,以后学会了再补)

posted @ 2024-01-23 16:33  黑屿白  阅读(10)  评论(0编辑  收藏  举报