8-22pdd服务端笔试
四道编程题,好难。。。
第一题给出商品的价值和下架时间(第几天下架),每天只能买一样商品,下架以后不能买,问最多能获得的价值。dp表示当前天数能获得的最大价值,先按下架时间从小到大排序,先往背包里放早下架的,这样晚下架的肯定能接着放进背包。AC
for (int i = 1; i <= n; i++)
for (int j = goods[i].time; j > 0; j--)
dp[j] = max(dp[j], dp[j-1]+goods[i].val);
for (int j = 1; j <= max_day; j++)
ans = max(ans, dp[j]); 第二题给出两个数字P和Q,P至少走几步能变成Q,有四种走法:P = P-1; P = P - 2; P = P + 1; P = P * 2。P和Q比较大,这题直到最后五分钟才改出来,花了很长时间,思路就是用队列放置下一步可以达到的值,但是不优化会直接爆内存溢出,优化思路:如果该值已经使用过不需要再入队列(队列前面的数字操作次数肯定更小)因此加一个hashMap做已访问标记,如果当前值now比Q大,实际上只能使用前面两种走法了,假设当前已经走了x步,那么到达Q需要走的步数就是x+(now-Q+1)/2,用这个值来更新ans,注意到x其实是队列的层数(深度),具体代码写的特别复杂,大致思路如下。AC queue<long long> que;
que.push(P);
long long ans = 0x3f3f3f3f;
long long x = 0;
while (1) {
int n = que.size();
for (int i = 0; i < n; i++){
long long now = que.front();
que.pop();
if (now >= Q) {
ans = min(ans, x+(now-Q+1)/2);
continue;
}
que.push(now+1);
que.push(now*2);
que.push(now-1);
que.push(now-2);
}
if (ans <= x) {
break;
}
x++;
} 第三题给出N和M,求一个最小的可以被M整除的N位整数。(N指的是十进制数位数,N和M都很大) 先构造一个N位的整数X,也就是1后面N-1个0,然后 X / M * M,如果结果超过了N位限制返回-1,由于N和M都很大我估计得写大整数除法乘法,遂放弃,小数据过了20%。
第四题题目特别长,有N个座位,每天会有一个新员工i入座到Pi位置,产生Li幸福度,假设任意一个员工j所在位置的区间[j-d,j+d]内所有员工幸福度之和超过了x则该员工特别幸运,这一天作为幸运日输出。感觉可能是用树状数组模拟吧,但是题目又臭又长,写不动,0%。
听朋友说pdd不喜欢校招,这个笔试有点劝退啊。。。
