题目链接
这题是一个标准的高中线性规划题,用线性规划的方法按部就班的解,就能做出来。
设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 <bits/stdc++.h>
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 <bits/stdc++.h>
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 按起来多带感(手动滑稽)