时间限制: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); } } }