小球下落 UVa679

    前面那种虽然直观易懂,但是需要的计算量太大,不符合算法竞赛的本来目的,放弃之。

    二叉树里面有大智慧的感觉,很像先民们留下的那句“两仪生四象,四象生八卦”的感觉。而且也和计算机的二进制有千丝万缕的联系,感觉这里面有很深的东西值得挖掘。

好吧,闲话不多说了。

    以后在遇到这种数量关系的,可以注意其奇偶关系。

    我感觉,这里还用到了一种叫做“递归治之”的策略。当然我的表述可能不太严谨。(原谅我表达能力太差)

    就是其实小球在每个节点上的操作其实都是一样的,他们的下落方向和奇偶性有些莫大的联系。根节点如此,下面的节点也是一样。所以每个小球,每到一个节点,都是一样的操作。

还是刘老师总结的好,对应给出的编号I。如果是奇数,就是往左走的第(I+1/2个小球;是偶数,就是往右走的第I/2的小球。

    换言之,如果你是第I个落在某个节点的小球,根据I的奇偶性,奇←偶→。这个一个单位的子问题,如果想要写出“递推方程”,那么就和下一个小球联系起来,显然,所有的小球都是以2个为一个小组往下落,于是也就有了I+1/2I/2

每一个单位子问题,一个是自身的变化,二一个就是和下面的联系。这也是“递推”思维。

    在本题中,K是自身的变化,而I是和下面的联系。每一次更新I,就像是抛弃了根节点,把现在这个节点视为根节点,做一次操作。

    #include<cstdio>
using namespace std;


int main() {
    int D,I;
    while(scanf("%d%d",&D,&I) == 2) {
        int k = 1;
        for( int i = 0; i < D-1; i++) {//下落D-1次
            if(k%2) { k = 2 * k + 1; I = (I + 1)/2; }
            else { k = 2 * k; I /= 2; }
        }
        printf("%d\n", k/2);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/huangming1644/article/details/79365068