#include<cstdio>
#include<cstring>
usingnamespace std;
constint maxd = 20;//对应题目中的D≤20
ints[1<<maxd];//<<运算符的意思是2的幂次方操作
//数据结构,一是数据,而是结构,二叉树是一种结构,但其实更重要的是数据,我们用计算机模拟小球下落,重要的是为了得到数据。所以用数组来存储值
intmain() {
intD,I;
while(scanf("%d%d",&D,&I)== 2) {
memset(s,0,sizeof(s));//每重新输入一次D和I,就对应一次重新模拟,所以要把数组清空,这地方易错。对应于题目中所说的“初始全部关闭”
intk , n = (1<<D) – 1;//n指的是最大的小球编号,与17行代码对应起来,就是为了防止小球出界
//要把头脑中可以想象出来的二叉树用计算机来实现,这是个难题,对于所有的题目来说,都是存在这样//的难题,这里的策略是,更多的去关注数据,结构的事情,用代码结构来实现,k就是要输出的数据。
for(inti = 0; i < I; i++) {//总共有I个小球,所以要I次循环。//作为算法竞赛,不是说只要把题目
//上的要求一句句按次序用代码实现就可以的。在用代码实现自己的想法时,更多的去关注结构,判断和
//循环语句尤其重要,抓住他们,用代码实现就很容易了、
k= 1;//每一次都是从1开始
for(; ; ) {
s[k]= !s[k];//对应“当每次有小球落到一个开关上时,状态都会改变,对于首节点也不例外”
k= s[k] ? k * 2; k * 2 +1;//操作顺序严格对应于题目中的叙述顺序。但是,如果往下落时,节点对应的是打开,因为已经被改变了,所以小球刚刚落下时,它面对的应该是一个关闭的结点,所以应该以关闭为准。这段稍微颠倒了以下,有点难以理解。
if(k> n) break;//虽然它严格下降D-1层,但是这样判断更具有代表性。
}
}
printf("%d",k/2);
}
return0;
}