百度2021校招C++PHP研发工程师笔试卷(9月3日)编程题解题报告 Apare

tech2024-10-09  12

百度2021校招C++/PHP研发工程师笔试卷(9月3日)编程题解题报告

2020.9.3


序言

单选题有15道,不定项选择题有5道(3份),选择题涉及的知识面很广,包括计网,Linux命令(df/du), AVL,二叉树,操作系统(生产者-消费者问题),数据结构,C++虚函数,java代码…编程题有3道,每道20份

第一题,铺地毯

题目描述:

T组数据,T<=1000, 在长度为L的走廊铺地毯,铺n块,每块的范围是[Left_i,Right_i]), n<=1000, 问最后每个位置的地板上有多少张地毯铺在上面。

思路:差分。[left,right]铺地板,那么差分数组a[left]++,a[right+1]–
#include <bits/stdc++.h> using namespace std; const int N = 2000; int a[N],b[N]; int main(void) { int T,L,n,x,y; cin>>T; while(T--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d%d",&L,&n); while(n--) { scanf("%d%d",&x,&y); a[x]+=1; a[y+1]-=1; } for(int i=1;i<=L;++i) { b[i] = b[i-1]+a[i]; } for(int i=1;i<L;++i) printf("%d ",b[i]); printf("%d\n",b[L]); } return 0; }

第二题:分配角色

T组输入,T<=100, n个人,m个角色。每个人分配一个角色,每个人的戏份的期望值为ai, 每个角色的戏份为bi。给每个人分配的角色的戏份必须不小于此人的期望值。否则无法分配。现在要求满足愿望的人数最大话,输出每个人分配的角色,如果没分配,输出-1

分析:贪心,把人按照戏份期望升序排列,角色用平衡二叉树(STL::set)维护,从头开始,每次分配能满足期望最小的角色(set::lower_bound),然后从书中删去这个角色。
#include <bits/stdc++.h> using namespace std; const int N = 1000+100; struct Node{ int id,want,op; bool operator < (const Node& rhs)const{ return want==rhs.want?id<rhs.id:want < rhs.want; } }node[N]; bool cmp(const Node& a,const Node& b) { return a.id < b.id; } int main(void) { int T,m,n; cin>>T; while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&node[i].want); node[i].id = i; node[i].op = -1; } set<pair<int,int> > st; pair<int,int> pr; for(int i=1;i<=m;++i) { pr.second = i; scanf("%d",&pr.first); st.insert(pr); } sort(node+1,node+1+n); for(int i=1;i<=n;++i) { pr.first = node[i].want; pr.second = 0; auto it = st.lower_bound(pr); if(it==st.end()) break; node[i].op = it->second; st.erase(it); } sort(node+1,node+1+n,cmp); for(int i=1;i<n;++i) { printf("%d ",node[i].op); } printf("%d\n",node[n].op); } return 0; }

第三题:走台阶

n步路,每次最少走1步,最多走m步。(n<=100,000,2<=m<=7), 每一步和前面的两部的步长都不能相同。问有多少种方案。

分析:肯定可以dfs(), 可以过40%的数据。我们DP。dp[i][j][k]代表当前在位置i,前一次走了k步,再前一次走了j步。(k!=j) , 那么dp[i][j][k] = (dp[i][j][k]+dp[i-k][fa][j])%mod;(fa!=j&&j!=k&&fa!=k), 我们可以强制令第一次走了0步,这样就使得至少走两次。
#include <bits/stdc++.h> using namespace std; const int N = 1e5+10; const int mod = 1e9+7; typedef long long LL; LL dp[N][8][8]; int record[N]; int cnt; void dfs(int x,int n,int m,int presum) { if(presum>n) return; if(presum==n) { ++cnt; // for(int i=0;i<x;++i) cout<<record[i]<<" ";cout<<endl; return; } int pre=-1,fa=-2; if(x-1>=0) pre = record[x-1]; if(x-2>=0) fa = record[x-2]; for(int i=1;i<=m;++i) { if(i==pre||i==fa) continue; record[x] = i; dfs(x+1,n,m,presum+i); } } int main(void) { int n,m; scanf("%d%d",&n,&m); // dfs(0,n,m,0); // cout<<cnt<<endl; for(int i=1;i<=m;++i) { dp[i][0][i] = 1; } for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { for(int k=1;k<=m;++k) { if(k==j) continue; if(i<j+k) continue; for(int fa=0;fa<=m;++fa) { if(fa==j||fa==k) continue; dp[i][j][k] = (dp[i][j][k]+dp[i-k][fa][j])%mod; } } } } LL ans = 0; for(int i=0;i<=m;++i) { for(int j=1;j<=m;++j){ if(i!=j) ans = (ans+dp[n][i][j])%mod; } } printf("%lld\n",ans); return 0; }

2020.9.3 21:18


最新回复(0)