这个程序常规处理起来数据量很大,I可以高达2^D-1
/*
.......
*/
里面的代码块据此避免了开太大的数组
做太多的循环
#include<cstdio> #include<cstring> const int maxd=20; int s[1<<maxd];//最大结点数2^maxd-1 int main(){ int D,I; /* while(scanf("%d%d",&D,&I)==2){ int k=1; for(int i=0;i<D-1;i++) 对I作判断,这里I是当前结点所遇到的第I个小球 if(I&1){ k=2*k; I=(I+1)/2;//I奇数,第(I+1)/2个往左走 } else{ k=k*2+1; I/=2;//I偶数,第I个往右走 } printf("%d",&k);//到达D-1层即叶子结点则输出K } */ while(scanf("%d%d",&D,&I)==2){ memset(s,0,sizeof(s)); int k,/*当前小球所在结点编号*/n=(1<<D)-1;//最大结点编号 for(int i=0;i<I;i++){ k=1;//从第一个结点开始 for(;;){ s[k]=!s[k]; k=s[k]?2*k:2*k+1;//闭左开右 if(k>n) break;//出界 } } printf("%d",k/2);//到叶子结点中去找原来的父结点 } return 0; }