【暑期实习】计算机视觉岗问题整理-快手

笔试部分

笔试部分前两道题相对比较简单,后两道题相对难一些,总体来说能拿到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),求中心在原点的单位球的表面,在椭球内部和在椭球外部的表面积分别是多少

分析

球表面积公式是(4pi 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;
}
原文地址:https://www.cnblogs.com/nomornings/p/13836861.html