代码改变世界

二叉树 小球下落 优化算法

2012-02-12 16:09  java环境变量  阅读(515)  评论(0编辑  收藏  举报

          

今天在算法书上看了一题,得到点感触,算法优化后效率可以提高很多。    所以不要停留在AC 的层面,AC了还应思考算法的效率。

 

/*题目大意,一个小球 从二叉树的上方往下掉。
   二叉树               1
                          2   3
                       4   5   6
                    7   8   9  10
                         。。。       

 每个节点是一个开关,开关关闭往左掉,开关开着往右掉。初始时全部关闭。
 输入二叉树的深度deep<=20,球的个数n,最后一个小球最后掉在哪个编号的袋子中。可能又10000组数据。

//自己写的(低效)
#include<stdio.h>
#include<string.h>
#define MAXN 1024*1024
int a[MAXN];
int main()
{
    int deep,n,i,j,k;
 while(scanf("%d%d",&deep,&n)!=EOF)
 {
  memset(a,0,sizeof(a));
  for(i=1;i<=n;i++)
  {
   k=1;
   for(j=1;j<deep;j++)
   {
    if(!a[k])         //开关关闭
    {
     a[k]=1;       //开启开关
     k=2*k;        //往左走
    }
    else              //开关开启
    {
     a[k]=0;        //关闭开关
     k=2*k+1;       //往右掉
    }
   }
  }
  printf("%d\n",k);
 }
 return 0;
}

//下面是算法书上看到的算法。用奇偶判断掉落方向,直接模拟最后一个球的路径。
//省去了大数组,省了很多运算 。
#include<stdio.h>
int main()
{
 int deep,n,i,k;
 while(scanf("%d%d",&deep,&n)!=EOF)
 {
  k=1;
  for(i=1;i<deep;i++)    //直接模拟最后一个球的路径
  {
   if(n%2)            //如果是第奇数个球
   {
    k=2*k;          //往左走
    n=(n+1)/2;      //同时,这个球是下一个节点的第(n+1)/2 个球
   }
   else               //如果是第偶数个球
   {
    k=2*k+1;        //往右走
    n=n/2;          //这个球是下一个节点的第n/2 个球
   }
  }
  printf("%d\n",k);
 }
 return 0;
}