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

百度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


猜你喜欢

转载自blog.csdn.net/qq_40531479/article/details/108393165