装备合成
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
输入描述:
输入包含t组数据
第一行一个整数t
接下来t行每行两个整数x,y
输出描述:
每组数据输出一行一个整数表示答案。
示例1
输入
复制
5
4 8
7 6
8 10
100 4555
45465 24124
输出
复制
2
2
3
50
13917
备注:
1<=t<=10000
1<=x,y<=1e9
题解:
两个做法一个三分,一个贪心
三分的做法
:
我们都知道 二分查找 适用于单调函数中逼近求解某点的值。
如果遇到凸性或凹形函数时,可以用三分查找求那个凸点或凹点。
假设A装备做了m件,B装备做了n件,我们固定m来求n
n=min( (x-2m)/4 , y-3m )就是看做完m剩下的材料,还能做多少个n,然后返回n+m,不断三分求出n+m的峰值,即最大值
代码:
#include<bits/stdc++.h>
using namespace std;
int x,y;
int check(int n){
return n+min((x-2*n)/4,y-3*n);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
cin>>x>>y;
int l=0;
int r=min(x/2,y/3);//目前 的x和y最多能做多少个m
while(l<r){
int mid1=l+(r-l)/3;
int mid2=r-(r-l)/3;
if(check(mid1)>check(mid2))r=mid2-1;
else l=mid1+1;
}
printf("%d\n",check(l));
}
return 0;
}
贪心的做法:
1.材料a特别多时,尽量用a来合成装备2,满足a>4b,b为多少就可以做多少件
2材料b特别多时,尽量用b来合成装备1,要满足3a<2*b,a为多少,就可以做a/2件
3.当两者差不多时,我们结合题目中两个式子:2a+3b=1,4a+b=1,我们可以得到a=1/5,b=1/5,也就是合成一件装备a+b必须是5的倍数,而且观察式子,a还必须是偶数。
所以如果a不是偶数,或者(a+b)不是5的倍数,结果就要减一
(相当于去除多余的材料,构成a为偶数,a+b为5倍数的情况)
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int t;
ll a,b;
int main() {
cin>>t;
while(t--) {
cin>>a>>b;
if(a>(b<<2)) printf("%lld\n",b);
else if(a*3<(b<<1)) printf("%lld\n",(a>>1));
else {
ll sum=(a+b)/5;
if(a&1&&(a+b)%5==0) --sum;
printf("%lld\n",sum);
}
}
}