链接:https://ac.nowcoder.com/acm/contest/5026/B
来源:牛客网
题目描述
最近米咔买了n个苹果和m个香蕉,他每天可以选择吃掉一个苹果和一个香蕉(必须都吃一个,即如果其中一种水果的数量为0,则他不能进行这个操作),或者使用魔法将某一种水果的数量翻倍。
现在米咔想吃西瓜了,但是他的主人赛小息不让他买新水果,除非苹果和香蕉没有了,即数量都是0了。
现在米咔想知道,最少用多少天他可以吃光苹果和香蕉。
可以证明的是,一定存在一种方案可以让米咔在若干天后吃光苹果和香蕉。
输入描述:
第一行一个正整数T(T≤100),代表数据组数。
接下来T行每行两个正整数n,m(n,m ≤100000)。
输出描述:
共T行,每行一个正整数代表答案。
示例1
输入
3
1 1
1 2
2 5
输出
1
3
7
说明
对于第三组测试样例(2,5),第一天令n翻倍变成(4,5),接下来连续吃三天水果变成(1,2),第五天令n翻倍变成(2,2),接下来连续吃两天水果,在第七天时吃光苹果和香蕉。
解题思路
1
首先解释一下为什么一定有一种方案,可以吃完。如果大家已经理解,直接跳过看2
假设a < b, 差值d = b - a;
1、如果a > d,则先每天各吃一个苹果和香蕉,这个时候差值d是不变的,直到a = d , 这时b = a + d=2a , 我们将a翻倍后,a = b , 然后再吃a天就可以吃完。
2、如果a < d,将a翻倍,直到满足情况1。
3、如果a = d,那么此时首先将a翻倍后,a = b,直接吃完就行。
所以该题一定有解。
2
在看到这到题的时候,脑子里肯定想到了要让a和b翻倍至数量接近之后,再一起吃,这样的话耗费的天数最小。可以举几个例子就能发现。
假设a<b;
则要让 a * 2 *n < = b ;n取最大值
当a翻倍到最大之后,再开始吃
代码(C++)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
int a,b;
while(t--)
{
int res=0;
cin>>a>>b;
if(a>b)
swap(a,b);
while(true)
{
if(a==b)
{
res+=a;
break;
}
if(a*2<=b)
{
a*=2;
res++;
continue;
}
a--;
b--;
res++;
}
cout<<res<<endl;
}
}