小球掉落问题
自我感觉,我们刷算法的小白阶段,会忽略很多方式的优化,就是简简单单的用暴力解决题目,最后发现自己不是漏条件,就是超时。
这个题目就就非常的典型,小白一看,诶?这个这个咋这么熟悉,我这不刚学完吗,看我给他建个树,里面再给他加一个标识符,诶,这不就解决了吗,我直接暴力,懂的多一点,我给他用记忆法优化一下,秒了!结果就是红红的超时。
实际上,这道题如果我们简单的归类一下 会发现小球的下落方向和他下落的顺序是有关系的,向左向右是和他下落的奇偶性有很强的相关关系,只不过小白不小心就忽落掉了。
代码和详解如下。
import java.util.Arrays;
import java.util.Scanner;
class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
sc.nextInt();
while (true) {
int n = sc.nextInt();
if (n == -1) {
return;
}
int m = sc.nextInt();
int k = 1;//记录节点
for(int i=0;i<n-1;i++){//一个数要分流n-1次(因为根节点不算)
if(m%2==1){//如果当前为奇数,说明
k = 2*k;//到左节点
m = (m+1)/2;//是往左走的(m+1)/2个
}else{
k = 2*k+1;//到右节点
m = m/2;//是往右走的m/2个
}
}
System.out.println(k);
}
}
}
在这个题中,每个节点在奇数球经过的时候,向左,在偶数球经过的时候向右,不明白可以把这个想象成一个开关。所以,一共有n个球,在经过一个节点的时候,如果他是奇数,就会有(n+1)/2个向左,n/2向右,偶数就是平方,总结得就是(n+1)/2向左,n/2向右,而这个n同时随着变化,然后,敲重点!!!这个n的变化(向左向右),就是最后一个球的变化!
核心就是这里,其它都比较好理解不再过多讲解