zoukankan      html  css  js  c++  java
  • 算法竞赛入门经典chapter6:二叉树~小球下落

    样例输入:

    4 2

    3 4

    10 1

    2 2

    8 128

    16 12345

    样例输出:

    12

    7

    512

    3

    255

    36358

    My Code
     1 #include<iostream>
     2 using namespace std;
     3 const int maxn = 20;
     4 
     5 int node[1<<maxn];
     6 int main()
     7 {
     8     int d, n;
     9     while(cin >> d >> n)
    10     {
    11         int s = 1<<d;
    12         memset(node, 0, s);//初始化结点全部关闭
    13         int i;
    14         while(n--)//n个小球
    15         {//结点状态为关闭则向左走,否则,向右走
    16             for(i = 1;  i < s; i = (!node[i]?(2*i+1):(2*i)))//注意:此处为结点的为改变之前的状态
    17                 node[i] = (node[i] ? 0 : 1);//改变结点状态
    18         }
    19         cout << (i+1)/2 << endl;
    20     }
    21     return 0;
    22 }

    每个小球都会落在根节点上,因此前两个小球必然是一个在左子树,一个在右子树。一般地,只需看小球编号的奇偶性,就能知道它是最终在哪棵子树中。对于那些落入根节点 左子树的小球来说,只需知道该小球是第几个落在根的左子树里的,既可以知道它下一步往左还是往右了。以此类推,直到小球落到叶子上。

    如果使用题目中给出的编号n,则当I是奇数时,它是往左走的第(n+1)/2个小球;当I是偶数时,它是往右走的对n/2个小球。这样,可以直接模拟最后一个小球的路线。改进如下

    Better
     1 #include<iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int d, n;
     7     while(cin >> d >> n)
     8     {
     9         int k = 1;
    10         for(int i = 0; i < d-1; i++)
    11             if(n%2)
    12             {
    13                 k *= 2;
    14                 n = (n+1)/2;
    15             }
    16             else
    17             {
    18                 k = k*2+1;
    19                 n /= 2;
    20             }
    21             cout << k << endl;
    22     }
    23     return 0;
    24 }

    优点是省略了一个巨大的数组。

  • 相关阅读:
    安装最新版Mysql(APT方式安装)
    Tengine环境安装
    Docker 教程
    Docker Redis
    Ubuntu
    spring boot actuator 如何显示详细信息
    spring boot 加载日志框架后经常出现 LOG_PATH_IS_UNDEFINED 目录怎么办?【未解决】
    Tomcat 目录结构以及基本配置
    Java Hash集合的equals()与hashCode() 方法
    Java Map 集合实现类
  • 原文地址:https://www.cnblogs.com/sanghai/p/2883787.html
Copyright © 2011-2022 走看看