sgu126 分类: sgu 2015-02-15 17:09 69人阅读 评论(0) 收藏
数学题
从最终状态逆退
我们用(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。
来自这里
#include<stdio.h>
#include<stdlib.h>
int lowbit(int x)
{
return x&(-x);
}
int gcd(int a,int b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
int main()
{
int a,b,g,tmp,ans=0;
#ifndef ONLINE_JUDGE
freopen("sgu126.in","r",stdin);
freopen("sgu126.out","w",stdout);
#endif
scanf("%d%d",&a,&b);
if(a==0 || b==0)printf("0");
else
{
g=gcd(a,b);
a/=g,b/=g;
if(a+b==lowbit(a+b))
{
tmp=(a+b)>>1,ans=0;
while(tmp)
{
ans++;
tmp>>=1;
}
printf("%d",ans);
}
else printf("-1");
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}