牛客练习赛59 4743 c 装备合成

题目链接
牛客练习赛59 4743 c 装备合成_第1张图片
牛客练习赛59 4743 c 装备合成_第2张图片
这题是一个标准的高中线性规划题,用线性规划的方法按部就班的解,就能做出来。
设n件装备采用方案一,m建装备采用方案二。

不过!

通过观察我们可以发现

  • 如果y远小于x的时候,能做出来的最大数量就只能是y了。
  • 如果x远小于y的时候,能做出来的最大数量就是x/2了。
  • 两种方案,消耗两种材料的总数都是5的倍数,2个a和3个b总共是五个,4个a和1个b也总共是五个,所以说,x+y>=5*ans(制作的装备数量)

到此,我们找到了一个结论,ans=min(x/2,y,(x+y)/5)
所以得到代码

#include 

using namespace std;
typedef long long ll;

int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll x, y;
    int t;
    cin >> t;
    while (t--) {
        ll ans = 0;
        cin >> x >> y;
        cout << min((x + y) / 5, min(x / 2, y)) << endl;
    }
    return 0;
}

此题结束

但是!

试一下这组案例

5 5

显然只能制作一件装备

通过上面代码得到的答案却是2!!!

问题就出在这个(x + y) / 5上,我们采用任何一种方案之后,剩下的材料都不足以进行制作装备,但它却刚好是5的倍数。
这时候应该怎么处理?
通过观察我们发现,两种方案,消耗a的数量一定是偶数,
所以,如果x为偶数,那么,当x+y刚好是5的倍数时,材料刚好能全部消耗完
如果x为奇数,那么,当x+y刚好是5的倍数时,制作完所有的装备后,剩下材料的数量也刚好是5的倍数,而这时却无法制作装备。
只有在这种条件下,我们的结论会给出正确答案+1
所以,我们只要判断这一种特例就行了,写一个if…else…

才怪!

a材料消耗的数量一定是偶数,而我们的结论出错的时候,x是奇数,所以我们只要在x为奇数的时候,让x-1,让剩余材料构不成5的倍数,不就解决了吗!

所以,根据位运算的性质,我们让x与上111111111111……11110,就能在x为奇数的时候,减一
得到代码

#include 

using namespace std;
typedef long long ll;

int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll x, y;
    int t;
    cin >> t;
    while (t--) {
        ll ans = 0;
        cin >> x >> y;
        x &= 0x7ffffffe;
        cout << min((x + y) / 5, min(x / 2, y)) << endl;
    }
    return 0;
}

其实还有一种写法,就是

x -= x % 2;

不过,你看这个 f 按起来多带感(手动滑稽)

你可能感兴趣的:(基本思想,数学)