您的位置:首页 > 其它

小球下落 UVa679

2018-02-24 20:21 302 查看
    前面那种虽然直观易懂,但是需要的计算量太大,不符合算法竞赛的本来目的,放弃之。     二叉树里面有大智慧的感觉,很像先民们留下的那句“两仪生四象,四象生八卦”的感觉。而且也和计算机的二进制有千丝万缕的联系,感觉这里面有很深的东西值得挖掘。 好吧,闲话不多说了。     以后在遇到这种数量关系的,可以注意其奇偶关系。     我感觉,这里还用到了一种叫做“递归治之”的策略。当然我的表述可能不太严谨。(原谅我表达能力太差)     就是其实小球在每个节点上的操作其实都是一样的,他们的下落方向和奇偶性有些莫大的联系。根节点如此,下面的节点也是一样。所以每个小球,每到一个节点,都是一样的操作。 还是刘老师总结的好,对应给出的编号I。如果是奇数,就是往左走的第(I+1)/2个小球;是偶数,就是往右走的第I/2的小球。     换言之,如果你是第I个落在某个节点的小球,根据I的奇偶性,奇←偶→。这个一个单位的子问题,如果想要写出“递推方程”,那么就和下一个小球联系起来,显然,所有的小球都是以2个为一个小组往下落,于是也就有了(I+1)/2、I/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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: