【暑期實習】計算機視覺崗問題整理-快手

筆試部分

筆試部分前兩道題相對比較簡單,後兩道題相對難一些,總體來說能拿到40+應該是沒什麼問題。

第一題

Questoin

給兩個整數\(K,N\),求將\(N\)分層\(K\)份後的最大乘積。

分析

這有點像是數學題,基本上每份差不多相等的時候就可以得到相乘最大值。

Answer

K, N = input().rstrip().split(' ')
K, N = int(K), int(N)

mean_N = int(N / K)
res = N - K * mean_N
result = mean_N**(K - res) * (mean_N + 1)**res

print(result)

第二題

Question

求二維矩陣從左上角到左下角的最小路徑,只能向下或者向右。

分析

把矩陣的邊界距離先求出來,然後用遞推的方式求解終點處的最小值。動態規劃的公式

\[dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + A[i][j] \]

Answer

class Solution:
    def find_best_path_cost(self, A):
        # write code here

        A_shape_w = len(A)
        A_shape_h = len(A[0])

        for i in range(1, A_shape_h):
            A[0][i] = A[0][i] + A[0][i - 1]
        for j in range(1, A_shape_w):
            A[j][0] = A[j][0] + A[j - 1][0]
        for i in range(1, A_shape_w):
            for j in range(1, A_shape_h):
                A[i][j] += min(A[i - 1][j], A[i][j - 1])
        return A[-1][-1]

第三題

Question

定義一種生成隨機序列的方式:給定\(S, A, B, P\), 初始\(arr[0] = S\), 接下來\(arr[i+1] = (arr[i] * A + B) % P\), 並且\(arr\)數組裏的每個數字最多出現兩次,當某個數字出現3次時,終止序列生成。給定兩組S, A, B, P分別生成兩個序列,求兩個序列的最長公共子序列.\(1≤S,A,B,P≤2000001\)

分析

我用的是模擬加動態規劃,模擬兩個數組太耗時了,應該是一個找規律的題目,裏面測試用例得到的序列結果爲:

[4, 3, 1, 3, 1]

[4, 1, 4, 1]

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0]

[1, 0, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2]

還沒有好好分析,等個大神出結果。下面是我的代碼。

Answer

k = int(input().rstrip())
for m in range(k):
    s = input().rstrip().split(' ')
    S, A, B, P = int(s[0]), int(s[1]), int(s[2]), int(s[3])
    a = []
    i = 0
    a.append(S)
    i += 1
    while (True):
        x = (a[i - 1] * A + B) % P
        if a.count(x) == 2:
            break
        a.append(x)
        i += 1

    s = input().rstrip().split(' ')
    S, A, B, P = int(s[0]), int(s[1]), int(s[2]), int(s[3])
    b = []
    i = 0
    b.append(S)
    i += 1
    while (True):
        x = (b[i - 1] * A + B) % P
        if b.count(x) == 2:
            break
        b.append(x)
        i += 1

    len_a = len(a)
    len_b = len(b)

    dp = [[0 for i in range(len_a + 1)] for j in range(len_b + 1)]

    for i in range(1, len_b + 1):
        for j in range(1, len_a + 1):
            if a[j - 1] == b[i - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

    print(dp[len_b][len_a])

第四題

Question

給定一個橢球:\((x-a)^2/d^2 + (y-b)^2/e^2 + (z-c)^2/f^2 = 1\),求中心在原點的單位球的表面,在橢球內部和在橢球外部的表面積分別是多少

分析

球表面積公式是\(4\pi r^2\)。採樣去近似,只拿了20%的分。來自快手算法筆試-A卷(只通過2.2, 太難了吧....) 下面是這種方法的代碼

Answer

#include <bits/stdc++.h>
using namespace std;
 
const double pi = acos(-1.0);
 
double a, b, c, d, e, f;
 
bool check(double x, double y, double z) {
    double s = (x-a) * (x-a) / d + (y-b)*(y-b)/e + (z-c)*(z-c)/f;
    return s <= 1;
}
 
int main() {   
    cin >> a >> b >> c >> d >> e >> f;
    d *= d, e*=e, f*=f;
    double step1 = 0.0005, step2 = 0.0005;
    double total = 0, inner = 0;
    for (double i = -1; i <= 1; i += step1) {
        double left = sqrt(1 - i * i);
        for (double j = -left; j <= left; j += step2) {
            double z = sqrt(1 - i*i - j*j);
            if (z != 0) total += 2, inner += check(i, j, z) + check(i, j, -z);
            else total += 1, inner += check(i, j, z);
        }
    }
    double A1 = inner / total * 4 * pi, A2 = 4 * pi - A1;
    cout << A1 << " " << A2 << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章