貝殼找房 2020校招 研發工程師試卷題解

貝殼找房 2020校招 研發工程師試卷題解

第一題

編程題|30.0分1/4

計算絕對值

**時間限制:**C/C++語言 1000MS;其他語言 3000MS
**內存限制:**C/C++語言 131072KB;其他語言 655360KB

題目描述:

給出n個正整數,要求找出相鄰兩個數字中差的絕對值最小的一對數字,如果有差的絕對值相同的,則輸出最前面的一對數。

2<n<=100,正整數都在10^16範圍內

輸入

輸入包含2行,第一行爲n,第二行是n個用空格分隔的正整數。

輸出

輸出包含一行兩個正整數,要求按照原來的順序輸出

樣例輸入

9
1 3 4 7 2 6 5 12 32

樣例輸出

3 4

AC 100% 代碼,簽到題,注意用long類型:

import java.util.Scanner;

/**
 * @author HGS
 * @date 2019/08/10
 */
public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] num = new long[n];
        for (int i = 0; i < n; i++) {
            num[i] = sc.nextLong();
        }
        long res = Long.MAX_VALUE;
        int idx = 0;
        for (int i = 1; i < n; i++) {
            if(Math.abs(num[i] - num[i-1]) < res){
                res = Math.abs(num[i] - num[i-1]);
                idx = i;
            }
        }
        System.out.println(num[idx-1] +" "+num[idx]);
    }
}

第二題

編程題|30.0分2/4

月光寶盒的密碼

**時間限制:**C/C++語言 1000MS;其他語言 3000MS
**內存限制:**C/C++語言 131072KB;其他語言 655360KB

題目描述:

小希偶然得到了傳說中的月光寶盒,然而打開月光寶盒需要一串密碼。雖然小希並不知道密碼具體是什麼,但是月光寶盒的說明書上有着一個長度爲 n (2 <= N <= 50000)的序列 a (-10^9 <= a[i] <= 10^9)的範圍內。下面寫着一段話:密碼是這個序列的最長的嚴格上升子序列的長度(嚴格上升子序列是指,子序列的元素是嚴格遞增的,例如: [5,1,6,2,4]的最長嚴格上升子序列爲[1,2,4]),請你幫小希找到這個密碼。

輸入

第1行:1個數N,N爲序列的長度(2<=N<=50000)

第2到 N+1行:每行1個數,對應序列的元素(-10^9 <= a[i] <= 10^9)

輸出

一個正整數表示嚴格最長上升子序列的長度

樣例輸入

8
5
1
6
8
2
4
5 
10

樣例輸出

5

AC 54 % 的數據 代碼

import java.util.Scanner;

/**
 * @author HGS
 * @date 2019/08/10
 */
public class Main {

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        int[] dp = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        int res = 0;
        for (int i = 1; i < n; i++) {
            int max = 1;
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    max = Math.max(max, dp[j] + 1);
                }
            }
            dp[i] = max;
            if(max > res){
                res = max;
            }
        }
        System.out.println(res);
    }
}

以上解法的時間複雜度爲 O(N2),可以使用二分查找將時間複雜度降低爲 O(NlogN)。

定義一個 tails 數組,其中 tails[i] 存儲長度爲 i + 1 的最長遞增子序列的最後一個元素。對於一個元素 x,

  • 如果它大於 tails 數組所有的值,那麼把它添加到 tails 後面,表示最長遞增子序列長度加 1;
  • 如果 tails[i-1] < x <= tails[i],那麼更新 tails[i] = x。

例如對於數組 [4,3,6,5],有:

tails      len      num
[]         0        4
[4]        1        3
[3]        1        6
[3,6]      2        5
[3,5]      2        nullCopy to clipboardErrorCopied

可以看出 tails 數組保持有序,因此在查找 Si 位於 tails 數組的位置時就可以使用二分查找。

public int lengthOfLIS(int[] nums) {
    int n = nums.length;
    int[] tails = new int[n];
    int len = 0;
    for (int num : nums) {
        int index = binarySearch(tails, len, num);
        tails[index] = num;
        if (index == len) {
            len++;
        }
    }
    return len;
}

private int binarySearch(int[] tails, int len, int key) {
    int l = 0, h = len;
    while (l < h) {
        int mid = l + (h - l) / 2;
        if (tails[mid] == key) {
            return mid;
        } else if (tails[mid] > key) {
            h = mid;
        } else {
            l = mid + 1;
        }
    }
    return l;
}

第三題

編程題|30.0分3/4

舉重大賽

**時間限制:**C/C++語言 1000MS;其他語言 3000MS
**內存限制:**C/C++語言 131072KB;其他語言 655360KB

題目描述:

舉重大賽開始了,爲了保證公平,要求比賽的雙方體重較小值要大於等於較大值的90%,那麼對於這N個人最多能進行多少場比賽呢,任意兩人之間最多進行一場比賽。

輸入

第一行N,表示參賽人數(2<=N<=10^5)

第二行N個正整數表示體重(0<體重<=10^8)

輸出

一個數,表示最多能進行的比賽場數

樣例輸入

5
1 1 1 1 1

樣例輸出

10

AC 100 % 代碼,排序優化一下就可過掉:

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author HGS
 * @date 2019/08/10
 */
public class Main {

    public static boolean canPlay(int a, int b) {
        if (a == b) {
            return true;
        }
        if (a < b) {
            return a * 10 >= b * 9;
        } else {
            return b * 10 >= a * 9;
        }
    }

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        Arrays.sort(nums);
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (canPlay(nums[i], nums[j])) {
                    cnt++;
                }else {
                    break;
                }
            }
        }
        System.out.println(cnt);
    }
}

第四題

特殊的測試

**時間限制:**C/C++語言 1000MS;其他語言 3000MS
**內存限制:**C/C++語言 131072KB;其他語言 655360KB

題目描述:

小C在做一種特殊的服務器負載測試,對於一個請求隊列中的請求,每一個請求都有一個負荷值,爲了保證服務器穩定,請求隊列中的請求負荷必須按照先遞增後遞減的規律(僅遞增,僅遞減也可以),比如[ 1,2,8,4,3 ],[ 1,3,5 ]和[ 10 ]這些是滿足規律的,還有一些不滿足的,比如[ 1,2,2,1 ],[ 2,1,2 ]和[ 10,10 ]。現在給你一個請求隊列,你可以對請求的負荷值進行增加,要求你調整隊列中請求的負荷值,使數組滿足條件。最後輸出使隊列滿足條件最小的增加總和。

輸入

輸入有兩行,第一行是N (1≤n≤5000) ,代表請求隊列中的請求數量。

第二行有N個數字 a1,a2…an (1≤ai≤10^9)。Ai是第i個請求的負荷值。

輸出

輸出這個最小增加總和

樣例輸入

5
1 4 3 2 5

樣例輸出

6

AC 100% 代碼,暴力過掉,注意結果用long類型

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author HGS
 * @date 2019/08/10
 */
public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        int[] temp = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        long res = Long.MAX_VALUE;
        long cnt;
        for (int i = 0; i < n; i++) {
            temp = Arrays.copyOf(nums, n);
            // 以 nums[i] 爲峯值中心,前面遞增,後面遞減
            cnt = 0;
            for (int j = 1; j <= i; j++) {
                if (temp[j - 1] >= temp[j]) {
                    int num = temp[j];
                    temp[j] = temp[j - 1] + 1;
                    cnt = cnt + temp[j] - num;
                }
            }
            for (int j = n - 2; j >= i; j--) {
                if (temp[j] <= temp[j + 1]) {
                    int num = temp[j];
                    temp[j] = temp[j + 1] + 1;
                    cnt = cnt + temp[j] - num;
                }
            }
            if (cnt < res) {
                res = cnt;
            }
        }
        System.out.println(res);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章