百度3道演算法題求解

軍說網事發表於2015-05-31

第一題:
某個公司舉行一場羽毛球賽,有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] 都沒有用到原陣列有序的特性,我想應該還能改進。

 

 

相關文章