前几天做了美团,OPPO的秋招笔试题,然后又做了一场小红书,总体难度我觉得都差不多,涉及到的知识点要么是语法模拟,或者就是一些基础算法,所以这样看秋招编程题还是很简单的,对于笔试我们还要把除了算法题以为的选择题做好,比如我看还有好多MySQL之类的题,好了话不多说,我们来看一下小红书2024秋招后端开发的题,先贴个链接 题目测评链接——
目录
A题
题面
思路分析
代码实现
B题
题面
思路分析
代码实现
C题
题面
思路分析
代码实现
总结
A题
题面
思路分析
首先我们按要求读入每个字符串,然后开一个map统计维护每个字符串的个数,如果该种字符串数量大于等于三,我们就将其放入pair数对里,因为题目中说明了排序输出方式,那我们需要对pair按要求开个cmp排个序就行了——
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#include <vector>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
typedef pair<string,int> PII;
PII p[N];
bool cmp(const PII &a,const PII &b)
{
if(a.y != b.y) return (a.y > b.y);
else return a.x < b.x;
}
void solve()
{
map<string,int> mp;
string str;
while(cin >> str)
{
mp[str]++;
}
// for(auto &c : mp) cout << c.x << " " << c.y << endl;
int i = 0;
for(auto &c : mp)
{
if(c.y >= 3)
p[i++] = {c.x,c.y};
}
sort(p , p + i ,cmp);
for(int j = 0; j < i; j++) cout << p[j].x << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
while(t -- ) solve();
return 0;
}
B题
题面
思路分析
这题其实就是01背包的变式问题,我们在01背包的基础上加了一维,变成了三维,不会01背包的可以先参考acwing这篇题解AcWing 2. 01背包问题(状态转移方程讲解) - AcWing 学习理解一下01背包之后再看这题就能知道怎么做了,我们定义一个dp[i][j][k],表示前i件事假在花费不超过j个时间和不超过k个精力下可以获得的最大快乐值,然后我们三重for循环,如果当前时间大于j或者精力大于k,则 dp[i][j][k] = dp[i - 1][j][k],表示不选,则和前一个状态一样。否则dp[i][j][k] = max(dp[i - 1][j][k] , dp[i - 1][j - a[i]][k - b[i]] + c[i]),即为当前状态选或不选,下面我们直接看代码——
代码实现
//01背包问题
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#include <vector>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 55;
int dp[N][510][510];
int a[N],b[N],c[N];
void solve()
{
int n;
cin >> n;
int T,H;
cin >> T >> H;
for(int i = 1; i <= n; i++) cin >> a[i] >> b[i] >> c[i];
for(int i = 0; i <= n; i++) dp[i][0][0] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= T; j++)
{
for(int k = 1; k <= H; k++)
{
//if(i == 1 && !((j < a[i]) || (k < b[i]))) dp[i][j][k] = c[i];
//else if(i == 1) continue;
if(a[i] > j || b[i] > k) dp[i][j][k] = dp[i - 1][j][k];
else dp[i][j][k] = max(dp[i - 1][j][k] , dp[i - 1][j - a[i]][k - b[i]] + c[i]);
}
}
}
cout << dp[n][T][H] << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
while(t -- ) solve();
return 0;
}
C题
题面
思路分析
按照题意我们求最多染红的节点肯定是想到贪心,优先染红子节点而非父节点,因为儿子节点有多个,父亲节点染色后与其关联的儿子节点都不能被染色,然后需要用到树的dfs去回溯执行染色操作,开两个数组,第一个vis判断节点有没有被访问过,第二个col进行染色操作——
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#include <vector>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
bool vis[N];//判断结点有没有被访问
bool col[N];//染色
int a[N];//存储权值
vector<int> G[N];//构造树
int res;
bool is_prime(int x)
{
if(x < 2) return false;
for(int i = 2; i <= x / i; i++)
{
if(x % i == 0) return false;
}
return true;
}
int dfs(int rt)
{
vis[rt] = true;
for(int i = 0; i < G[rt].size(); i++)
{
int son = G[rt][i];
// cout << son << endl;
if(vis[son] == true) continue;
dfs(son);
if(is_prime(a[son] + a[rt]))
{
if(col[rt] == 0)
{
col[son] = 1;
// cout << rt << " " << son << endl;
res++;
}
}
}
return res;
}
void solve()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n - 1; i++)//注意不能读n个
{
int u,v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
cout << dfs(1) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
while(t -- ) solve();
return 0;
}
总结
最后其实我觉得小红书这场笔试题目质量还是很不错的,对于我们训练有着很好的意义,加油——