笔试部分
笔试部分前两道题相对比较简单,后两道题相对难一些,总体来说能拿到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
求二维矩阵从左上角到左下角的最小路径,只能向下或者向右。
分析
把矩阵的边界距离先求出来,然后用递推的方式求解终点处的最小值。动态规划的公式
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;
}