百度3道算法题求解

第一题:
某个公司举行一场羽毛球赛,有1001个人参加,现在为了评比出最厉害的那个人,进行淘汰赛,请问至少需要进行多少次比赛。

第二题
100个灯泡,第一轮把所有灯泡都开启,第二轮把奇数位的灯泡灭掉,第三轮每隔两个灯泡,灭一个,开一个,依此类推。求100轮后还亮的灯泡。

第二题目说错了: 重新在描述一遍,sorry

一百个灯泡排成一排,第一轮将所有灯泡打开;
第二轮每隔一个灯泡关掉一个。即排在偶数的灯泡被关掉,
第三轮每隔两个灯泡,将开着的灯泡关掉,关掉的灯泡打开。
依次类推,第n轮结束的时候,还有几盏灯泡亮着。


第三题
20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。

 

一、

1.如果不考虑内部排名而仅寻找最强的那个人。即最底层有1001个节点的完全二叉树的度为2的节点数
2.三个循环
3.5路归并排序?

 

二、

第一个 不能用二叉数 只能用n2时间相关的算法, 因为要选 最厉害的, 因为是比赛不是排序 所以会出现一种情况 就是就是石头剪刀布的情况, 所以要两两 都对战一场,看谁赢的局数多。

 

三、

#include <stdio.h>

  

#define PRINT    {for (i = 0; i < 100; i++)printf("%d ", ar[i]);printf("\n\n");}

// 0   关着的

// 非0 开着的

int main(void)

{

    int ar[100] = {0};

    int i;

    int times;

    int n;

    int t;

    printf("n = ?: ");

    scanf("%d", &n);

    for (i = 0; i < 100; i++)

        ar[i] = 1;

    for (t = 1; t < (n % 100); t++)

    {

        for (i = 0; i < 100; i += (t + 1))

            ar[i] = !ar[i];

        PRINT

    }

    for (i = 0, times = 0; i < 100; i++)

        if (ar[i] != 0)

            times++;

    printf("%d", times);

    return 0;

}

 

四、

1. 1000
2. 灯泡从 1 开始编号,所有编号为完全平方数(1,4,9,...,100)的灯泡最后会亮着。ps.这个是经典题了。
3. 昨天刚好看到类似的题目。以下 n=10000,m=500,有三个方法。
   [1] sort. O(nlogn)
   [2] 将第一数组建立 min-heap,所有其他数组成员依次插入到 min-heap,每次完成插入后,删除当前最小值,即根元素。所有元素都筛过以后,min-heap 中的元素即为最大的 500 个。O(nlogm).
   [3] 将 20 个数组合并为 1 个,挨着连接起来即可,不必保证有序。在合并的数组中随机选取一个元素,然后将所有小于此元素的元素放在其左侧,大于到右侧。完成操作后,如果原来被选中的元素刚好处在右数第 500 的位置,那从它开始向右的元素即为所求。否则,如果右端元素数目大于 500,则对右端序列递归使用此方法;否则,如果左端序列数目大于 10000-500,则对左端序列递归使用此方法。复杂度 expected O(n). 
   [2] 和 [3] 都没有用到原数组有序的特性,我想应该还能改进。

 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。