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;
}
posted @ 2015-02-15 17:09  <Dash>  阅读(141)  评论(0编辑  收藏  举报