創新工場筆試題目


創新工場編程題

9月16日,創新工場校招筆試題:

1.輸入一個整型無序數組,用堆排序的方法是數組有序

2.求一個正整數的開方,要求不能使用庫函數sqrt,結果精度在0.01即可

3.給定一個矩陣int matrixA[m][n],每行沒列都是增序的,實現一個算法尋找矩陣中的某個元素element

下面做出我的題解,能力有限,望見諒! 

第一題:堆排序

  考的排序算法中的堆排序,這里稍微講一下堆排序的算法:

  二叉樹:

  基本概念:

  大根堆:  就是說父節點要比左右孩子都要大。

  小根堆:  就是說父節點要比左右孩子都要小。

  算法:

  1、從最后一個父結點開始,從后往前遍歷樹的所有二叉樹的父節點,構造大頂堆;

  2、整個數都是大頂堆,那么樹的根節點肯定是數組中的最大值,將其與最后一個元素交換swap,這時可能會破壞大頂堆,需要重新構建大頂堆,然后再取樹的根節點與最后一個點交換,依次類推……

代碼如下:

#include <stdio.h>
#include <stdlib.h>
void Heapadjust(int *arr, int parent, int cnt)
{
    int child;
    int ValParent;
    for(ValParent = arr[parent]; 2 * parent + 1 < cnt; parent = child)
    {
        child = 2 * parent + 1; //父節點的左子節點
        //右子節點存在且大於左子節點,則child+1
        if(child + 1 < cnt && arr[child] < arr[child + 1])
        {
            child++;
        }
        //若子節點大於根節點,則把子節點的值賦給根節點,否則跳出循環;跳出循環的原因是:
        //既然是從最后一個父節點開始往前構大根堆,如果父節點滿足大根堆,那其子節點也滿足大根堆
        if(arr[child] > arr[parent])
        {
            arr[parent] = arr[child];
        }
        else
        {
            break;
        }
        //沒有跳出循環說明,父節點與子節點值交換了,那有可能會導致大根堆被破壞,所以要檢查子節點
        //是否還是大根堆
        arr[child] = ValParent;
    }

}
void Swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void HeapSort(int *arr, int cnt)
{
    int iter = 0;
    //初始化大根堆,根據大根堆的特征,可以減少判斷的次數
    for(iter = cnt / 2 - 1; iter >= 0; iter--)
    {
        Heapadjust(arr, iter, cnt);
    }

    //大根堆的第一個數是最大的,將它與數組最后一個數作交換,每次交換都前移數組的尾數索引
    //交換過程中可能會導致大根堆遭破壞,所以要調用Heapadjust(arr, 0 , iter)構建大根堆
    //由於前面已經初始化大根堆,所以已經具備大根堆的特征,不需要再一個一個父節點的慢慢構建
    //只需要將Heapadjust的第二個參數設置為0,即大根堆的第一個父節點即可
    for(iter = cnt - 1; iter >= 0; iter--)
    {
        Swap(&arr[0], &arr[iter]);
        Heapadjust(arr, 0 , iter);
    }
}

int main(void)
{
    int arr[] = {3, 2, 1, 4, 5 ,7 ,6, 12, 34, 34 ,56};
    int len = 11;
    HeapSort(arr, len);
    int i = 0;
    for( i = 0; i < len; i++)
    {
        printf("%4d",arr[i]);
    }
    return 0;
}
View Code

第二題:二分法

  直接使用二分法即可解答問題,但是題目中所說的是正整數的開方,我覺得完全可以擴展到浮點型的開方,浮點型開方需要注意一點問題,就是大於1和小於1的情況不一樣,比如0.9的平方是0.81,而我們是從0到0.81取二分的,顯然肯定找不到0.9這個數,所以要稍作處理。

/*
   分治法求平方根
*/
#include <stdio.h>
#include <stdlib.h>
#define EPSION 0.000001
double MySqrt(double des)
{
    double low = EPSION;
    double high = EPSION;
    double mid = 0.0;
    double sqr = 0.0;
    high = des > 1.0 ? des : des + 1.0;
    do
    {
        mid = (low + high) / 2.0;
        sqr = mid * mid;
        if(sqr > des)
        {
            high = mid;
        }
        else
        {
            low = mid;
        }
    }while((sqr - des) < -EPSION || (sqr - des) > EPSION);
    return mid;
}
int main(void)
{
    double num = 0.0;
    do
    {
        printf("The number :");
        scanf("%lf", &num);
        if(num < 0)
        {
            printf("input error! Please input again!\n");
        }
    }while(num < 0);
    printf("Its sqrt is %.4lf\n", MySqrt(num));
    return 0;
}
View Code

第二題:楊氏矩陣查找

  矩陣為MatrixA[m][n],要找的數字為element,從第一行的最后一列的數MatrixA[0][n - 1]開始查找,element比MatrixA[0][n - 1]小則向左查找,否則向下查找,直到找到該數時退出。圖示如下:(可能就會有多個element,只需找到其中一個返回是否存在即可)

 

 

相應的代碼:

/*
    楊氏矩陣:查找
*/
#include <stdio.h>
#include <stdlib.h>
#define M 4
#define N 4
int FindElement(int MatrixA[M][N], int element)
{
    int i = 0, j = N - 1;
    while(1)
    {
        while(MatrixA[i][j] >= element)
        {
            if(MatrixA[i][j] == element) return 1;
            j--;
            if(j < 0) return 0;
        }
        while(MatrixA[i][j] <= element)
        {
            if(MatrixA[i][j] == element) return 1;
            i++;
            if(i >= M) return 0;
        }
    }
}
int main(void)
{
    int MatrixA[M][N] = {{1, 3, 4, 8},
                         {3, 5, 6, 9},
                         {6, 7, 10, 11},
                         {7, 8, 12,15},
                        };

    int i = 0;
    for(i = 1; i <= 15; i++)
    {
        printf("element: %-3d", i);
        switch(FindElement(MatrixA, i))
        {
            case 0: printf("don't exist!\n"); break;
            case 1: printf(" exist!\n"); break;
            default: break;
        }
    }
    return 0;
}
View Code

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM