我们用(x, y)表示两个盒子里分别有x个球和y个球(不区分是哪个盒子)。假设总共有n个球,经过k步把所有球移到一个盒子里。如果反过来推的话,那么各盒子中球的个数为:
第k步: (0, n);
第k-1步:(n/2, n/2);
第k-2步:(n/4, 3n/4);
第k-3步:(n/8, 7n/8)或(3n/8, 5n/8);
第k-4步:(n/16, 15n/16)或(3n/16, 13n/16)或(5n/16, 11n/16)或(7n/16, 9n/16);
......
这样,我们就发现了规律:除(0, n)这种情况外(一步即可),若(A, B)能化成(x*c, y*c)这种形式,(c为A、B的最大公约数,x和y均为奇数且x+y=2^k,k=1,2,...)则k即为所求的最小步数,输出k;否则,输出-1。
最大公约数是左边的2*3不是下面的
http://baike.baidu.com/link?url=mmkLljBbVMlc-gYEwmhx8dCSQWu7QasBxeYlM_fSbgrTxPkH-Rl9s9tvvpd8Ei4-
<pre name="code" class="cpp">
#include<iostream>
#include<cstring>
using namespace std;
int a,b;
int gcd(int a,int b)
{
if(a>b)
swap(a,b);
int t;
t=b%a;
while(t)
{
b=a;
a=t;
t=b%a;
}
return a;
}
int main()
{
while(cin>>a>>b)
{
int ans;
if(a==0||b==0) //排除0 0, 1 0, 2 0这些情况
ans=0;
else
{
int k=gcd(a,b);
a=a/k;
b=b/k;
k=a+b;
ans=0;
while(k>1)//K必须大于1如果是while(k)则结果都是-1;
{
if(k%2==0)
{
ans++;
k=k/2;
}
else
{
ans=-1;
break;
}
}
}
cout<<ans<<endl;
}
return 0;
}